In a two-node Proxmox cluster, Corosync’s quorum mechanism can quickly become a sticking point: if the “main” node goes down, the “secondary” node finds itself alone and loses quorum, which makes the cluster unusable. The more nodes you have, the more voters and capacity you have to work with in your cluster.
Here, we want to have a second Proxmox server that doesn’t actually take part in quorum decisions. This prevents the cluster from locking up when only a single node is active, while still keeping the ability to run demo virtual machines on the secondary server. This article describes how to disable the secondary node’s Corosync vote and ensure the cluster’s stability.
I needed to build this kind of two-node cluster for my PVMSS application, to test the application’s capabilities against a Proxmox cluster. However, I don’t need several worker nodes, only one will be active.
To avoid the “split-brain” problem while keeping the second server solely as a test/placeholder machine, you need to:
- Remove its voting right (weight = 0).
- Tell Corosync that this is a two-node cluster, where quorum must be calculated based on a single real vote.
The heart of the problem lies in the votes parameter. By assigning votes: 0 to the secondary node, you remove it from the quorum calculation. You also tell Corosync that it should expect only a single real vote (expected_votes: 1) and you enable the special two-node mode (two_node: 1). This combination ensures the cluster works as long as the main node is online, and that the second node causes no “split-brain”.
Modify the corosync.conf file on the main node#
The corosync.conf file cannot be modified while the services that use it are running. Log in to the main node, where you’ll make the changes. Stop the corosync and pve-cluster services:
systemctl stop pve-cluster
systemctl stop corosyncNow, you need to use the pmxcfs command to explore the Proxmox filesystem and make changes to it. Run pmxcfs -l, and the following messages should appear:
[main] notice: resolved node name '<nom_node>' to '<ip_node>' for default node IP address
[main] notice: forcing local mode (although corosync.conf exists)Before making any changes, it’s essential to create a backup copy of the configuration file with a simple “cp”: cp /etc/pve/corosync.conf /etc/pve/corosync.conf.bak.
Edit the file /etc/pve/corosync.conf and add the following changes:
totem {
...
config_version: 2 # increment this value before saving the corosync.conf file
...
}
nodelist {
node {
name: nom_node1
nodeid: 1
quorum_votes: 1 # main node: normal voting right
...
}
node {
name: nom_node2
nodeid: 2
quorum_votes: 0 # secondary node: no voting right, set to 0
...
}
}
quorum {
provider: corosync_votequorum
expected_votes: 1 # The quorum expects only 1 real vote
two_node: 1 # Enables "two-node" mode (avoids split-brain)
wait_for_all: 0
}quorum_votes: 0removes the second node’s voting right.expected_votes: 1indicates that quorum will be reached as soon as a single vote (that of the main node) is present.two_node: 1enables the special two-node mode: if the main node disappears, the second node keeps working in “standalone” mode (no cluster lockup), but it won’t be able to take the main node’s place until quorum is restored.wait_for_all: 0prevents corosync from waiting for the votes of all the cluster members.
Save the changes made to the file, exit the local mode of the pmxcfs command, and restart the services:
killall pmxcfs && systemctl restart corosync.service pve-cluster.serviceThe actions will be replicated to the second node. If that’s not the case, log in to the second node, restart the pve-cluster and corosync services, then make sure the /etc/pve/corosync.conf file is identical to the first node’s.
With the pvecm status command, check that the cluster’s second machine no longer has its voting right:
root@node1:~# pvecm status
Cluster information
-------------------
Name: clustername
Config Version: 3
Transport: knet
Secure auth: on
Quorum information
------------------
Date: Sat Nov 1 21:36:19 2025
Quorum provider: corosync_votequorum
Nodes: 2
Node ID: 0x00000001
Ring ID: 1.266
Quorate: Yes
Votequorum information
----------------------
Expected votes: 1
Highest expected: 1
Total votes: 1
Quorum: 1
Flags: 2Node Quorate WaitForAll
Membership information
----------------------
Nodeid Votes Name
0x00000001 1 172.16.0.1 (local)
0x00000002 0 172.16.132.240Result#
The secondary server becomes a “placeholder node”: it stays visible in the cluster, can host test VMs, but never influences Corosync’s decision-making process. The cluster remains fully functional even if the main node goes down, thanks to the two_node mode.
Sources#
- Proxmox VE — Cluster Manager (quorum, two_node, expected votes)
- corosync-quorumtool / votequorum (
man votequorum) — details thetwo_node,expected_votesandwait_for_alloptions.
