The production phase begins: building a Vault High Availability Cluster using Raft Integrated Storage. We'll cover the active-standby architecture, 3-node cluster setup, raft join, leader election, quorum, and common mistakes to avoid.

After covering Vault's integration with Terraform and Ansible in episode 19 — making Vault the source of truth when infrastructure is provisioned automatically — this episode marks the start of Phase 6: HA, Hardening, Observability & Production Readiness. And we begin this final phase from the most crucial foundation: building a Vault High Availability (HA) Cluster with Raft Integrated Storage.
You might think, "why bother making a cluster? Vault already runs on my single server." True — but imagine this scenario: your apps fetch secrets from Vault on every bootstrap, dynamic database credentials are opened through Vault, and internal TLS certificates are issued by Vault. Now that Vault server dies due to disk failure or routine maintenance. What happens? Every application that needs new secrets goes down with it. A single-node Vault is a single point of failure (SPOF) — one point that can take down the entire system.
This isn't theory. In the real world, Vault is one of the components that is most "relied upon but forgotten" until it dies. Like a heart: while it beats normally you don't notice it, but the moment it stops, the whole body stops. This episode teaches you how to make Vault stay alive even when one — or even two — of its nodes die, plus understanding the protocol that guarantees data consistency behind it: Raft.
Before diving into configuration, let's clarify why a single node is never acceptable in production:
The HA concept in Vault is simple: it doesn't mean several nodes serve all requests in parallel. The architecture is one Active node serving read and write requests, surrounded by one or more Standby nodes that replicate all data and are ready to take over when the Active node fails. This episode focuses on how that replication works and how to manage it correctly.
Since Vault version 1.4, you no longer need to provision separate external storage to build a cluster. Vault has Raft Integrated Storage — a distributed storage backend embedded directly in the Vault binary.
| Storage Backend | Source | External Requirements | Consensus | When Suitable |
|---|---|---|---|---|
file | Vault | None | None | Lab / single node (not production) |
consul | Vault | Separate Consul cluster | Consul (Raft) | Legacy setup, already have Consul |
raft | Vault | None | Built-in Raft | Modern production standard |
The main advantages of Raft integrated storage:
vault operator raft snapshot save) which we'll cover in episode 22.In one Vault cluster, there's only one Active node. All write requests (writing secrets, creating tokens, issuing certificates) and read requests are served by this node. The Standby nodes are responsible for:
HTTP 307 redirect to the Active node's address. So from the client side, there's no need to know which node is active.Note
There's a variant called Performance Standby (an Enterprise feature) that can also serve read requests to reduce the Active node's load. For Vault Open Source, only one node serves all requests — so make sure the Active node has enough capacity, and failover speed is a primary concern.
Leader election is done with the Raft Consensus protocol. Each node has a role: leader (active) or follower (standby). When the leader stops sending heartbeats, followers start an election. A decision is only made if a majority of nodes (quorum) agree — this is where the protection against split-brain lies.
Now it's time to practice. We'll build a 3-node cluster with the IPs:
vault-node-1 → 10.0.0.11vault-node-2 → 10.0.0.12vault-node-3 → 10.0.0.13The core configuration of each node is nearly identical — what differs is only node_id, api_addr, and cluster_addr. Note the storage "raft" block:
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-node-1"
retry_join {
leader_api_addr = "https://10.0.0.11:8200"
}
retry_join {
leader_api_addr = "https://10.0.0.12:8200"
}
retry_join {
leader_api_addr = "https://10.0.0.13:8200"
}
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = false
tls_cert_file = "/etc/vault.d/tls/vault.crt"
tls_key_file = "/etc/vault.d/tls/vault.key"
}
api_addr = "https://10.0.0.11:8200"
cluster_addr = "https://10.0.0.11:8201"
ui = true
log_level = "Info"Important things about the configuration above:
node_id must be unique on every node — it's the node's permanent identity in the cluster. If node_id is the same, Raft will reject the node joining.retry_join contains the addresses of all nodes that could become the leader. When a node boots and isn't yet part of the cluster, it keeps trying to "find" the cluster through these addresses.api_addr is the address clients see; cluster_addr is the address for inter-node Vault communication (port 8201). Both are required so failover and redirects work correctly.Warning
Use a stable IP or hostname for api_addr and cluster_addr. Don't use localhost or 127.0.0.1 — other nodes can't reach it. In the cloud, a private IP or an internal DNS resolvable between nodes is commonly used.
Run Vault on all three nodes, then initialize only the first node:
export VAULT_ADDR=https://10.0.0.11:8200
vault operator initThe result is Unseal Keys (Shamir) and the Initial Root Token. Store them safely — we're still using manual unseal in this episode (auto-unseal will be covered in episode 21). Then unseal the first node:
vault operator unseal "Unseal Key 1"
vault operator unseal "Unseal Key 2"
vault operator unseal "Unseal Key 3"Once the threshold is met, node-1 becomes sealed=false. This node automatically becomes the cluster leader because no other node exists yet.
Now node-2 and node-3 join the cluster. The vault operator raft join command needs the leader's address (or the api_addr of one of the existing nodes):
export VAULT_ADDR=https://10.0.0.12:8200
vault operator raft join https://10.0.0.11:8200The successful output is roughly:
Key Value
--- -----
Joined trueNode-2 and node-3 also need to be unsealed with the same Unseal Keys (the cluster's master key is one — shared across all nodes):
vault operator unseal "Unseal Key 1"
vault operator unseal "Unseal Key 2"
vault operator unseal "Unseal Key 3"From any node (with a valid token), we can check the cluster's health:
export VAULT_ADDR=https://10.0.0.11:8200
vault statusKey Value
--- -----
Sealed false
HA Enabled true
HA Cluster vault-cluster-abc123
HA Mode active
Active Since 2026-08-02T08:15:00.000ZNote the lines HA Enabled true and HA Mode active — these are the signs that the node is serving requests. Now look at the cluster map with vault operator raft list-peers:
vault operator raft list-peersNode Address State Voter
---- ------- ----- -----
vault-node-1 10.0.0.11:8201 leader true
vault-node-2 10.0.0.12:8201 follower true
vault-node-3 10.0.0.13:8201 follower trueAll nodes show voter as true — meaning they participate in consensus decisions. Node-1 is the leader, the other two are followers.
Tip
To test failover, stop the Vault process on node-1 (e.g. systemctl stop vault). Wait a few seconds, then run vault operator raft list-peers from node-2 — one of the followers will automatically be elected the new leader. This is an exercise you must do before claiming the cluster is "production-ready."
The key to understanding Raft is the quorum concept: the majority number of nodes that must agree before the cluster makes a decision. The formula: quorum = floor(n/2) + 1. For 3 nodes, quorum = 2. That means at least 2 nodes must be alive for the cluster to keep working.
| Node Count | Quorum (majority) | Safe Node Failures | Fatal Node Failures |
|---|---|---|---|
| 1 | 1 | 0 | 1 |
| 3 | 2 | 1 | 2 |
| 5 | 3 | 2 | 3 |
| 7 | 4 | 3 | 4 |
From the table above you can see why 3 nodes is the minimum viable production configuration, and 5 nodes for highly critical environments. With 3 nodes, one node failure is safe; two node failures mean losing quorum. With 5 nodes, two node failures are still safe.
Important
When quorum is lost, Vault can't write new data and can't elect a new leader. Worse, after a certain period (usually a few minutes), the cluster will automatically seal itself for safety — because it can't guarantee consistency. This isn't a bug, it's intentional behavior: better to refuse service than serve inconsistent data.
Real-world Vault HA operational experience is full of traps. Here are the most common:
| Mistake | Impact | Solution |
|---|---|---|
Duplicate node_id | Node fails to join or data gets mixed | Ensure node_id is unique; use host/instance names |
api_addr/cluster_addr wrong or localhost | Broken failover, redirects don't work | Always use a stable IP/DNS reachable by other nodes |
Storage path on a shared filesystem (NFS) | Raft data corrupted by race conditions | Every node must have its own local disk |
| Unseal only on some nodes | Failover happens but the replacement node is still sealed | Always unseal all nodes; or use auto-unseal (episode 21) |
| Removing a node without procedure | Cluster still counts the dead node as a voter | Use vault operator raft remove-peer with the proper procedure |
| Split brain assumed possible | Excessive panic during leader election | Raft prevents split-brain via quorum; as long as the majority is alive, data is safe |
One thing worth emphasizing: never just delete the /opt/vault/data folder on a failed node to "reset" it. If that node is still counted as a voter, the cluster still considers it part of the quorum and this can kill the cluster entirely. Use the official command to deactivate the node from the cluster's perspective before taking physical action.
Caution
Adding a new node to an unhealthy cluster is a common cause of disaster. The rule of thumb: fix the cluster's health first (normal quorum), only then change the topology. Don't patch a dying cluster with new nodes — you risk worsening the inconsistency.
In this episode 20 we understood why a single-node Vault is unsuitable for production, how Raft Integrated Storage provides distributed storage without external dependencies, how the Active-Standby architecture works, and how to build a 3-node cluster step by step: the storage "raft" configuration, vault operator raft join, initialization, unseal, and verification with vault operator raft list-peers. We also learned the quorum table — 3 nodes for standard production, 5 nodes for critical environments — plus a list of common mistakes that often destroy clusters in the real world.
One thing you definitely noticed in practice: after every server restart, you must manually unseal with the Unseal Keys. In production, this is an operational nightmare — who guarantees an operator is awake at 3 AM when the maintenance window ends? The good news is there's an elegant solution: auto-unseal using Cloud KMS, which we'll cover thoroughly in episode 21. With auto-unseal, Vault unseals itself automatically at boot — without human intervention. Keep your enthusiasm up, we still have five exciting final episodes!