Skip to main content
RunBook Academy

Proxmox VEXI · ClusteringCluster internals

What /etc/pve does when quorum is lost

Advanced⏱ ~26 minpvecmpmxcfs

What you'll learn

  • State exactly which operations survive quorum loss and which fail, and explain why the split falls where it does
  • Recognise an inquorate cluster from its symptoms before reading pvecm status
  • Explain what pmxcfs -l does, what it costs, and the narrow conditions under which it is defensible
  • Verify that a recovered cluster is genuinely writable again rather than assuming it from a green GUI

Prerequisites

Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12

Not yet marked complete on this device.

There is one sentence in this lesson that is worth more than the rest of it:

pmxcfs serves reads without quorum and rejects every write.

Every confusing thing about an inquorate Proxmox cluster is a consequence of that asymmetry. The web interface loads, because loading it is a read. The guest list is populated, because that is a read. The VMs are running, because they were already running and a running QEMU process does not re-read /etc/pve. And then you click Start on a stopped guest, or edit a description, or try to migrate something, and it fails with an error that does not mention quorum at all.

The operator conclusion at that point is almost always “the GUI is broken”. It is not. The cluster is telling you, in the only way it has, that it does not currently have the right to change its own mind about anything.

The rule, stated precisely

/etc/pve is not a directory on a disk. It is a FUSE mount point backed by pmxcfs, which the Proxmox documentation describes as “a database-driven file system for storing configuration files, replicated in real time to all cluster nodes using corosync”.

Replicated in real time is the operative phrase. A write to /etc/pve is not a local file write that is later synchronised; it is a cluster-wide ordered transaction. Ordering a transaction across a set of nodes requires knowing which nodes are in the set, and that is exactly what quorum establishes. With no quorum there is no agreed membership, so there is no way to order a write, so the write is refused.

Reads have no such requirement. The node already holds a complete copy of the configuration in memory. Serving it costs nothing and risks nothing.

OperationInquorate nodeWhy
Reading any file under /etc/pveWorksServed from the local in-memory copy
Web interface loads, guest list populatesWorksReads only
Already-running VMs and containers keep runningWorksQEMU and LXC do not consult /etc/pve after start
Guest disk and network I/OWorksNothing in the data path touches pmxcfs
SSH to the node, journalctl, top, zpool statusWorksNot cluster state
Writing any file under /etc/pveFailsNo agreed ordering
qm set, pct set, creating or destroying a guestFailsWrites the guest config file
Starting a stopped guestFailsNeeds the cluster lock, which is a pmxcfs write
Live migration in either directionFailsWrites the config on the target node
Adding or editing storage, users, firewall rules, HA resourcesFailsAll of these live in /etc/pve
HA recovery of a failed guestDoes not happenThe LRM cannot act without quorum
Backups to PBSUsually failsvzdump takes a cluster-wide lock
Read-only / Safethe cheapest possible confirmation
# touch /etc/pve/quorum-probe
touch: cannot touch '/etc/pve/quorum-probe': Permission denied

Illustrative output

Reading the evidence

Read-only / Safepvecm status on a node that has lost quorum
# pvecm status
Cluster information
-------------------
Name:             prod-cluster
Config Version:   7
Transport:        knet
Secure auth:      on

Quorum information
------------------
Date:             Wed Aug 12 02:41:19 2026
Quorum provider:  corosync_votequorum
Nodes:            1
Node ID:          0x00000002
Ring ID:          2.1a4
Quorate:          No

Votequorum information
----------------------
Expected votes:   3
Highest expected: 3
Total votes:      1
Quorum:           2 Activity blocked
Flags:

Membership information
----------------------
  Nodeid      Votes Name
0x00000002          1 10.0.0.12 (local)

Illustrative output

Activity blocked is the string to remember. Corosync prints it when the current partition holds fewer votes than the quorum threshold, and it is the authoritative statement that writes are being refused.

What is still safe to do while you are inquorate

An inquorate cluster is a frozen cluster, not a broken one. The workloads are running. Nothing is corrupting. You have time, and the correct use of that time is diagnosis, not intervention.

Read-only / Safethe inquorate-cluster triage sequence
set -euo pipefail

# 1. Confirm the diagnosis and see which partition you are in.
pvecm status

# 2. Which peers can this node actually see at the corosync layer?
#    -n lists nodes with per-link status; -s shows this node's link health.
corosync-cfgtool -n
corosync-cfgtool -s

# 3. What did corosync say as it happened? The membership change is logged.
journalctl -u corosync --since '30 min ago' --no-pager

# 4. Is pmxcfs itself healthy, or is the daemon the problem rather than quorum?
systemctl status pve-cluster --no-pager

# 5. Are the guests actually still running, whatever the GUI says?
qm list
pct list

Point 5 is worth dwelling on, because it is the reassurance that lets you slow down. qm list reads the config from /etc/pve and the run state from the local system. If it shows your guests as running, they are running, they are serving traffic, and the business impact so far is “no changes can be made” rather than “the service is down”.

pmxcfs -l, and what it actually costs

pmxcfs accepts three options. Only one of them matters operationally:

OptionDocumented as
-d, --debug“Turn on debug messages”
-f, --foreground“Do not daemonize server”
-l, --local“Force local mode (ignore corosync.conf, force quorum)”

Read that description carefully, because it is doing more than it looks like. Local mode does not ask for quorum and does not wait for it. It ignores corosync.conf entirely and asserts quorum unilaterally, which makes /etc/pve writable on this node with no coordination with any other node whatsoever.

That is occasionally the only tool that works. There are three situations where it is the right answer:

  1. corosync.conf itself is broken. It lives inside /etc/pve, which is read-only without quorum, which requires a working corosync.conf. That circular dependency is exactly what local mode exists to break.
  2. A single surviving node after a genuine disaster, where the others are verifiably destroyed and you need to edit configuration to bring services back.
  3. Recovering configuration from a node you are about to reinstall.

And there is one situation where it destroys data: two nodes in local mode at the same time, on either side of a network partition. Both are writable, both accept changes, and neither knows about the other. There is no merge algorithm in pmxcfs. When corosync comes back, one version of the truth wins and the other is gone.

Cluster-wide risklast resort: bring pmxcfs up in local mode on ONE node
set -euo pipefail

# PRECONDITION, and it is not optional: every other node is confirmed OFF
# through iDRAC / iLO / IPMI, or physically. A node you cannot reach is not
# a node that is off.

systemctl stop pve-cluster

# Foreground and debug, so you can see what it is doing and stop it with
# Ctrl-C rather than leaving a daemon in local mode by accident.
pmxcfs -l -f -d

# In a second session: /etc/pve is now writable on this node only.
# Make the single change you came here to make - typically repairing
# corosync.conf - and nothing else.

# Then stop the foreground process (Ctrl-C) and return to normal operation:
systemctl start pve-cluster
pvecm status

Verifying that you are actually recovered

A green GUI is not verification. The GUI was green throughout the outage. Verification means demonstrating a write, and demonstrating it on the node you care about.

Read-only / Safeprove the cluster is writable again
set -euo pipefail

# 1. Quorate, with the vote count you expect for a healthy cluster.
pvecm status | grep -E 'Quorate|Total votes|Expected votes'

# 2. Every node present and every link up.
corosync-cfgtool -n

# 3. The actual test: a real write to /etc/pve, then clean up after it.
#    A temporary file in the cluster root is replicated like anything else.
PROBE=/etc/pve/.quorum-probe-$(hostname -s)
date -Is > "$PROBE"
cat "$PROBE"
rm -f "$PROBE"

# 4. Confirm the write reached a peer. Run this on a DIFFERENT node while
#    the probe file still exists to see replication rather than local state.

# 5. If HA is configured, the manager should be back to a normal state
#    rather than sitting in a wait or error state.
ha-manager status

Step 3 is the one that can fail, which is what makes it verification. If date -Is > "$PROBE" returns Permission denied, you are still inquorate regardless of what any dashboard says.

Common mistakes

  • Restarting services to fix a read-only /etc/pve. pveproxy, pvedaemon and pvestatd are downstream of the problem. Restarting them changes nothing and lengthens the incident.
  • Concluding the storage is broken because pvesm status shows inactive storages. Storage definitions live in /etc/pve/storage.cfg; an inquorate node can still read them, but pvestatd updates and some activation paths need a writable cluster.
  • Running pmxcfs -l on more than one node. There is no recovery from this other than choosing a winner and discarding the other node’s changes.
  • Treating “the VMs are still up” as evidence that nothing is wrong. It is evidence that nothing is wrong yet. Nothing will fail over, nothing will restart, and no backup will run until quorum returns.
  • Using /etc/pve as a general-purpose replicated share. The 128 MiB ceiling is for the entire cluster configuration, and exhausting it is a cluster-wide fault.

Key takeaways

  • Reads succeed without quorum; writes are refused. Everything else follows.
  • The error messages never say “quorum”. pvecm status and the Activity blocked string are the fast diagnosis.
  • Running guests are unaffected, which buys you time to diagnose properly instead of intervening.
  • pmxcfs -l ignores corosync.conf and forces quorum on one node. It is for a broken corosync.conf or a genuinely dead cluster, never for an active partition.
  • Verify recovery with a write that can fail, on every node.

Knowledge check

Knowledge check · 5 questions

  1. Q1. An operator reports that the Proxmox web interface loads normally and shows all guests running, but every attempt to start a stopped VM fails with a 500 error. What should be checked first?

  2. Q2. A three-node cluster is partitioned and one node finds itself alone. Which of the following continue to work on that isolated node? Select all that apply.

  3. Q3. Before running pmxcfs -l on a surviving node, every other node must be confirmed powered off or fenced through out-of-band management, rather than merely being unreachable over the network.

  4. Q4. Why does pmxcfs return an error on a write rather than queueing it for replay once quorum returns?

  5. Q5. Which of these is genuine verification that a cluster has recovered from quorum loss?

Passing score: 75%. Answers are checked in this browser.