# Formation of Clusters
When a [`Raft`] node is created by [`Raft::new()`], it enters the [`Learner`] state.
To establish a cluster, invoke [`Raft::initialize()`].
[`Raft`]: `crate::Raft`
[`Learner`]: `crate::core::ServerState::Learner`
## [`Raft::initialize()`]
This method will:
- Add a membership log at index 0 with the log id `(leader_id=LeaderId::default(), index=0)`.
The membership will be immediately effective.
- Transition to the [`Candidate`] state and initiate voting to become the leader.
[`Candidate`]: `crate::core::ServerState::Candidate`
- The leader will commit a blank log to commit all previous logs.
### Recommended Usage
The simplest and most appropriate way to initialize a cluster is to call `initialize()`
on **exactly one node**. The other nodes should remain empty and wait for the initialized
node to replicate logs to them.
Calling `initialize()` on multiple nodes with **identical configuration** is also
acceptable and will not cause any consistency issues — the Raft voting protocol ensures
that only one leader will be elected.
However, calling `initialize()` with **different configurations** on different nodes
may lead to a split-brain condition and must be avoided.
### Errors and Failures
- If this method is called on a node that has already been initialized, it will simply return an error and remain safe,
i.e., if `last_log_id` on this node is not `None`, or `vote` on this node is not `(0,0)`.
### Preconditions for Initialization
The legal initialization conditions are as follows:
The initial membership log with log id `(leader_id=LeaderId::default(), index=0)` will be appended to a node without consensus.
This must not violate the commit condition:
1. Log id `(leader_id=LeaderId::default(), index=0)` must not exceed any committed log id.
If `leader_id` is not the smallest value, i.e., `(term=0, node_id=0)`, it may be greater than some
committed log id. This is why the first log must be the smallest: `((term=0, node_id=0), 0)`.
2. A node should not append a log that is smaller than its `vote`.
Otherwise, it is effectively altering the **history** seen by other nodes.
This may (but not necessarily) disrupt consensus, depending on the protocol.
For example, if the cluster has been running a fast-paxos-like protocol, appending a smaller log than `vote` is illegal.
By prohibiting the appending of a smaller log than `vote`, it will always be safe.
For these two reasons, appending the first log is only allowed if:
`vote==(0,0)`. This is why the initial value of `vote` must be `(0,0)`.
[`Raft::initialize()`]: `crate::Raft::initialize`
[`Raft::new()`]: `crate::Raft::new`