Build a 3-Node Proxmox VE Cluster
Join three separate machines into one Proxmox VE cluster with real quorum, so you can manage every host from one UI and live-migrate a running VM between them without downtime.
What you'll build and why
Three separate, unremarkable machines become one Proxmox VE cluster: a single web UI that manages all three, a shared cluster configuration every node agrees on (quorum), and the ability to live-migrate a running virtual machine from one physical box to another without it ever going down. This is the same underlying idea every cloud provider runs on, at homelab scale.
Don't build this if: you have one machine, or you're not sure you'll ever need more than one. A single Proxmox VE node does everything this guide's cluster does except survive losing a node and live-migrate between hosts -- for one machine, install Proxmox VE standalone and skip clustering entirely; adding cluster complexity you don't use is pure cost. You also don't need this if your goal is genuinely just running a handful of containers on a Raspberry Pi -- a Docker host with Portainer (see the Docker Compose homelab stack guide) gets you there with far less to learn and maintain.
This guide gets you to a healthy, quorate 3-node cluster with confirmed live migration. It does not cover High Availability (automatic VM restart after a node failure) or shared storage -- those are the next two guides in this series, and depend on the cluster this one builds.
How it works
Every node runs pve-cluster, which keeps a replicated cluster filesystem (/etc/pve) in sync across all members, and corosync, which handles the low-level "who's alive and who agrees on what" messaging between nodes over the network. Corosync uses UDP ports 5405-5412 and needs consistently low latency (under 5ms) between every pair of nodes -- it doesn't need much bandwidth, but it's sensitive to jitter and delay, which is why Wi-Fi is explicitly not recommended for it.
Quorum is how the cluster avoids two halves of a broken network both thinking they're in charge (a "split-brain"). It's simple majority voting: with 3 nodes, any 2 that can talk to each other hold quorum and the cluster keeps functioning; a node that can't see a majority stops making changes to cluster state, even if it's still running fine on its own. This is why 3 is the practical minimum for a cluster that tolerates a real failure, and why going to 4 nodes without also going to 5 buys you nothing -- 4 nodes still only tolerates losing 1 before quorum is at risk, identical to 3, for the cost of a 4th machine. (Proxmox also supports a 2-node cluster with a QDevice -- a lightweight third vote-only participant on separate hardware -- as an alternative to a full 3rd node; this guide uses 3 full nodes since that's the more common homelab path and needs no extra device.)
┌─────────────────────┐
│ Gigabit switch │
└──┬───────┬───────┬──┘
│ │ │
┌─────────┘ │ └─────────┐
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ pve1 │ │ pve2 │ │ pve3 │
│.1.101 │◄───►│.1.102 │◄───►│.1.103 │
│ │ │ │ │ │
│ corosync │ │ corosync │ │ corosync │
│ UDP │ │ UDP │ │ UDP │
│ 5405-5412 │ │ 5405-5412 │ │ 5405-5412 │
│ │ │ │ │ │
│ web UI │ │ web UI │ │ web UI │
│ :8006 │ │ :8006 │ │ :8006 │
└────────────┘ └────────────┘ └────────────┘
Corosync traffic: every node <-> every node, all the time.
Management (web UI, SSH): your workstation -> whichever node
you happen to be looking at -- cluster config is shared, so
it doesn't matter which one.
Before you start
Prerequisites:
- Comfortable installing a Linux-based OS from USB and navigating a BIOS/UEFI boot menu
- Can set a static IP address (on the router's DHCP reservation, or in the OS itself)
- Three machines that meet the hardware minimums above, on the same switch
Decision: which filesystem for each node's boot/local storage?
The installer asks once per node, and it's a real trade-off, not a formality:
| Option | Pick this if | Trade-off |
|---|---|---|
| ext4 (this guide's choice) | You want the simplest, most predictable option for a first cluster | No snapshots, no built-in replication -- you'll add those later (see the HA/storage-replication guide) when you're ready |
| ZFS (RAID1/mirror across 2 disks) | You have 2+ disks per node and want snapshots and bit-rot protection from day one | Needs more RAM (ZFS's ARC cache wants headroom beyond the bare minimum), and undoing a ZFS layout choice later means reinstalling |
| BTRFS | You want snapshots without ZFS's RAM appetite (newer Proxmox option) | Less battle-tested in the Proxmox ecosystem than ZFS; fewer people to ask when something's unusual |
This guide uses ext4 because it has the fewest moving parts while you're still learning whether clustering itself works -- you can convert to a different storage backend later without touching the cluster membership.
Nothing existing gets modified -- this guide assumes three machines you're installing fresh onto. If any of the three currently holds data you care about, back it up before starting: the installer will offer to wipe the target disk, and confirming that is irreversible.
Plan your addressing before you touch any hardware. This guide uses:
pve1 192.168.1.101
pve2 192.168.1.102
pve3 192.168.1.103
Substitute your own subnet, and pick addresses outside your router's DHCP range so nothing else gets handed these later.
Steps
Step 1: Flash the installer and boot each node
Flash the Proxmox VE ISO to your USB drive with balenaEtcher or Rufus, default settings. Reuse the same drive for all three installs -- no need to re-flash between machines.
Boot each machine from the USB in turn (most BIOS/UEFI menus: hold F11/F12/Esc during power-on to pick the boot device).
Why this order: doing all three installs before touching networking or clustering means any hardware problem (a dead NIC, an unsupported disk controller) surfaces early, on one machine at a time, instead of in the middle of a cluster-join attempt.
Step 2: Install Proxmox VE on each node
At the boot menu: Install Proxmox VE (Graphical).
- Accept the EULA, select the target disk, choose ext4 (see the filesystem decision above)
- Set country, time zone, keyboard layout -- get the time zone right specifically, since corosync is sensitive to clock drift and a wrong time zone makes later log timestamps misleading
- Set a root password and an email (used for local alert mail; any address works for a homelab)
- Network page:
- Hostname (FQDN):
pve1.local(thenpve2.local,pve3.local) - IP address: this node's static address from the plan above
- Gateway: your router's address
- DNS server: your router's address, or
1.1.1.1if you'd rather not depend on local DNS
- Hostname (FQDN):
Repeat for all three machines with their own hostname/IP. Expected output: each node reboots to a console showing its web UI address, https://<node-ip>:8006.
Step 3: Confirm each node is healthy before clustering anything
Log into each node's web UI separately (https://192.168.1.101:8006, then .102, .103) as root. Accept the self-signed certificate warning -- expected until you install a real one later.
Check on every node:
- Datacenter → node name → Summary: correct hostname and IP
- Time sync, via a shell (web UI's Shell button, or SSH):
$ timedatectl
Expected output: System clock synchronized: yes. Why this matters: cluster formation can fail on clock drift alone, and it's a much harder problem to diagnose after nodes are already joined than to fix now.
Step 4: Create the cluster on the first node
Pick one node to start with -- it has no lasting special status once the cluster exists, this only matters for this one step. This guide uses pve1.
In pve1's web UI: Datacenter → Cluster → Create Cluster.
- Cluster Name: short and stable, e.g.
homelab - Cluster Network (Link 0): the interface each node uses for corosync traffic -- on a single-NIC setup this is your only choice
Click Create. Expected output: within a few seconds, Datacenter → Cluster shows pve1 as a member, alone.
Step 5: Join the remaining nodes
On pve1: Datacenter → Cluster → Join Information → Copy Information.
On pve2: Datacenter → Cluster → Join Cluster. Paste the copied information, then enter pve1's root password when prompted (this authenticates the join -- it's not pve2's own password). Click Join.
Expected output: pve2's web UI drops the connection for 10-30 seconds while it reconfigures as a cluster member. Log back in; the left sidebar now lists every cluster node from any single node's UI, since cluster configuration is shared.
Repeat identically on pve3.
Command-line alternative to the wizard, if you'd rather script it: pvecm add 192.168.1.101 run on the joining node, or pvecm add 192.168.1.101 --link0 <local-ip> if corosync should use a specific local interface.
Step 6: Verify quorum from a shell
From any node's Shell or SSH:
$ pvecm status
Expected output: Quorate: Yes, and a Membership information table listing all 3 nodes with 1 vote each. If it says Quorate: No, or lists fewer than 3 nodes, stop and work through Troubleshooting below before building anything on top of this cluster.
Verify it works
-
pvecm statuson any node showsQuorate: Yeswith 3 members, 1 vote each - All 3 node names appear in the left sidebar from any single node's web UI
- Create a test VM on
pve1-- it becomes visible (though not running, if not started) frompve2andpve3's UI too - Start that VM, then migrate it: right-click the VM → Migrate → target
pve2. It completes without errors and the VM keeps running throughout if it was already on - Failure test: power off
pve3(pull the plug -- don't shut it down gracefully; you're testing an unplanned loss). Runpvecm statusonpve1orpve2. Expected: stillQuorate: Yeswithpve3shown as offline -- 2 of 3 nodes hold a majority. Powerpve3back on and confirm it rejoins automatically (its name reappears as online within roughly a minute, no manual re-join needed).
Secure it
- What's exposed: each node's web UI (
:8006) and SSH (:22) listen on every interface by default -- this guide assumes they're only reachable from your LAN, not forwarded through your router. Don't port-forward8006or22to the internet; if you need remote access, use a VPN back into your network (see the WireGuard guide) so the cluster's management surface is never directly internet-facing. - Default credentials: there aren't separate "default" credentials to change here -- you set the root password during install (Step 2). Make it a real password, not something you plan to change later; there's no forced-rotation prompt.
- Secrets: the root password authenticates cluster joins (Step 5) and isn't stored anywhere outside your own memory/password manager by this guide -- don't put it in a script or commit it anywhere.
- Least privilege: for anything beyond your own solo lab use, create non-root users with scoped permissions (Datacenter → Permissions → Users) instead of sharing the root login -- out of scope for this guide, but don't skip it if more than one person touches this cluster.
- Update strategy: Proxmox VE security advisories are published at the Proxmox Security Advisories page. Update via
apt update && apt full-upgradeon each node (do them one at a time, not all simultaneously, so quorum never drops below majority mid-upgrade), or through the web UI's Updates section. - The failure that hurts most: losing quorum by taking down more than one node at once for "just a quick reboot," which halts cluster-wide changes until majority is restored. The step that prevents it: never plan maintenance windows that overlap across more than one node in a 3-node cluster (see Troubleshooting).
Back it up and maintain it
What matters: the cluster configuration itself lives in /etc/pve (replicated automatically to every node by pve-cluster -- you don't need to back this up separately, since any surviving node has a full copy). What you do need to back up is VM/container data, which this guide doesn't create a durable backup path for on its own -- Proxmox Backup Server or scheduled vzdump (covered in the CLI reference guide) to storage outside this cluster is the next real step once you have VMs worth protecting.
Update cadence: apply Proxmox VE updates monthly at minimum, and promptly for anything flagged as a security advisory. One node at a time (Secure it, above).
What to monitor: disk space on each node's boot/local storage (a full disk on any node degrades that node's ability to write cluster state), and pvecm status's quorum line if you've ever had a node go flaky -- a node that's quietly dropping in and out is worth catching before it happens during real maintenance.
Troubleshooting
Logs: journalctl -u corosync -n 100 and journalctl -u pve-cluster -n 100 on the node in question are the first place to look for anything cluster-related.
| Symptom | Likely cause | Diagnostic | Fix |
|---|---|---|---|
pvecm status shows Quorate: No |
A node hasn't finished joining, a firewall is blocking corosync, or clocks have drifted | journalctl -u corosync -n 50 on the affected node; timedatectl on every node |
Wait a minute and re-check if mid-join. If a firewall exists beyond Proxmox's own, allow UDP 5405-5412 between all node IPs. Fix any node whose clock isn't synchronized. |
| A node join fails immediately with a certificate/fingerprint error | The join information was copied too long ago or from the wrong node | Re-open Join Information on the source node and compare the fingerprint shown | Regenerate: Datacenter → Cluster → Join Information → Copy Information again, paste fresh |
| Cluster loses quorum after one node goes down for maintenance | Expected if a second node is also down -- 3-node quorum needs 2 of 3 | pvecm status -- check the vote count |
Never overlap maintenance windows across more than one node in a 3-node cluster |
| VM migration fails with a storage-related error | VM disks are on node-local storage only; live migration can't move a disk that isn't on shared/replicated storage | Check the VM's Hardware → Disk storage target | Expected at this stage -- shared or replicated storage (NFS, Ceph, ZFS replication) is the next guide, not this one |
| A newly-joined node never appears in the sidebar on other nodes | The join technically failed partway through, or that node's pve-cluster service isn't running |
systemctl status pve-cluster on the new node; journalctl -u pve-cluster -n 100 |
Restart pve-cluster on the affected node (systemctl restart pve-cluster); if that doesn't resolve it, remove the node from the cluster config and re-join from scratch |
| Web UI shows "TLS handshake failed" or similar between nodes after a join | Clock drift severe enough to invalidate the internal cluster certificates' validity window | timedatectl on all nodes; compare timestamps in journalctl -u pve-cluster across nodes |
Fix time sync first (Step 3), then retry the join |
Undo
To remove a node from the cluster: on a different node (not the one being removed), Datacenter → Cluster, select the node, click Remove. If the node being removed is offline, this still works (Proxmox's own docs note the resulting harmless "could not kill node" message can be ignored). To fully decommission a node afterward, reinstall Proxmox VE on it standalone, or repurpose the hardware entirely.
To dissolve the whole cluster and return every node to standalone: remove nodes one at a time via the method above until one remains, then on that last node stop and disable clustering services (systemctl stop pve-cluster corosync, systemctl disable pve-cluster corosync) or simply reinstall it standalone if you don't need to preserve its VMs.
Go further
- Proxmox HA: Automatic VM Failover Across Nodes -- the direct next step: shared/replicated storage plus automatic restart if a node dies outright
- Proxmox VE Command-Line Reference -- the CLI commands for day-to-day cluster/VM/container management
- Set up scheduled backups (Proxmox Backup Server or
vzdump) to a non-clustered target before you put anything you'd miss on this cluster - Add a 4th node's worth of budget toward a 5-node cluster instead, once you outgrow 3 -- not toward a 4th, which buys no additional fault tolerance
- Configure real TLS certificates for the web UI instead of the self-signed default, once this cluster is something other than a lab
Resources
Official documentation:
- Cluster Manager -- the full clustering reference this guide is based on
- Proxmox VE Administration Guide -- hardware requirements, general administration
- High Availability -- read before the HA follow-on guide
Source and releases:
- Proxmox VE source repositories -- Proxmox VE is built from these Debian-packaged components
- Proxmox VE Security Advisories -- where updates worth prioritizing get announced
Community:
- Proxmox VE Community Forum -- the project's own forum, more authoritative for Proxmox-specific issues than general homelab communities
- r/Proxmox -- active, homelab-skewing discussion
Go deeper:
- Proxmox VE Cluster Manager wiki -- covers corosync redundant-link configuration and QDevice setup this guide didn't need
- Corosync's own documentation -- for understanding the cluster-communication layer itself beyond what Proxmox's wrapper exposes
Related DaemonPress projects:
Last verified: 2026-09-21, checked against official Proxmox VE documentation (see Resources above). Not lab-tested on physical hardware this revision -- the previous version of this guide was written from general knowledge without live verification; this rewrite corrected the corosync port range (previously unstated), added the QDevice alternative, the CLI join method, and the filesystem decision table, none of which were in the original.
Changelog:
- 2026-09-21 -- Full rewrite to the Build content-type standard: added How it works diagram, filesystem decision table, Secure it, Back it up and maintain it, Undo, and a full Resources section; expanded Troubleshooting from 3 to 6 entries with diagnostic commands; added a failure test to Verify it works; corrected/added version specificity (Proxmox VE 9.2.12); moved from the
homelabcategory tovirtualization-containers. - 2026-09-20 -- Original version published.