Skip to main content
RunBook Academy

Proxmox VEXII · High AvailabilityHA fundamentals

What HA requires: the storage, network and fencing matrix

Advanced⏱ ~24 minha-managerpvesm

What you'll learn

  • Classify every storage backend by whether it permits HA recovery and why
  • Predict what happens to a guest on local storage when its node fails
  • State the network and fencing prerequisites and explain why each is load-bearing
  • Run a readiness check that fails, rather than assuming HA is ready because it was enabled

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.

ha-manager add vm:100 succeeds on any guest, on any storage, on any cluster with quorum. The interface shows a green HA tab. ha-manager status reports the service as started. Every dashboard agrees the VM is protected.

None of that is a statement about whether HA can recover it. PVE does not validate the prerequisites at enable time, and the first thing that tests them is a node failure.

This lesson is the check that should happen instead.

The requirements, from the documentation

The official list is short:

at least three cluster nodes (to get reliable quorum), shared storage for VMs and containers, hardware redundancy (everywhere), use reliable “server” components.

Each of those is load-bearing in a different way, and the third and fourth are the ones people read as advice rather than as requirements.

Storage: the matrix

The question a backend must answer is: can a surviving node open this guest’s disks, right now, without the failed node’s cooperation?

BackendSharedHA recoveryWhat actually happens
Ceph RBDYes✔ FullAny node with a working cluster connection opens the image
CephFSYes✔ FullSame, for file-based guest storage
NFSYes✔ FullAny node that can mount the export
iSCSI + LVMYes✔ FullShared LUN; PVE’s locking prevents concurrent activation
ZFS over iSCSIYes✔ FullThe target owns the ZFS pool; nodes are clients
CIFS/SMBYes✔ FullSame shape as NFS
LVM on shared SANYes✔ FullRequires the SAN to present the LUN to all nodes
ZFS local + replicationNo✘ PartialRecovery to the last replicated snapshot, with data loss
LVM-thin (local)No✘ NoneNo surviving node can see the volume
Directory (local)No✘ NoneSame
ZFS local, no replicationNo✘ NoneSame
Read-only / Safewhich of your storages are actually shared
set -euo pipefail

pvesm status --output-format json-pretty | head -30

# The declarations, including the shared flag on each entry.
grep -E '^\s*(dir|nfs|cifs|lvm|lvmthin|zfspool|rbd|cephfs|iscsi|pbs)|shared' \
/etc/pve/storage.cfg

What actually happens to a guest on local storage

Not “HA does not work”. Something specific, and knowing which is the difference between a five-minute diagnosis and an hour.

Read-only / Safean HA service that has nowhere to go
# ha-manager status
quorum OK
master pve-02 (active, Tue Aug 11 03:42:17 2026)
lrm pve-01 (old timestamp - dead?, Tue Aug 11 03:38:02 2026)
lrm pve-02 (active, Tue Aug 11 03:42:19 2026)
lrm pve-03 (active, Tue Aug 11 03:42:20 2026)
service vm:100 (pve-01, error)
service vm:101 (pve-02, started)

Illustrative output

The sequence, in order:

  1. pve-01 stops sending heartbeats. The CRM notices.
  2. The failed node self-fences via its watchdog, or the CRM waits out the fencing timeout. This takes on the order of a minute; it is not instant and it is not meant to be.
  3. The CRM moves vm:100 to recovery and looks for a node that can run it.
  4. Every surviving node reports that it cannot access the guest’s storage.
  5. The service goes to error state and stays there. Nothing further happens automatically.

The guest is down, and it stays down until an operator intervenes. That is the correct behaviour - the alternative is starting a VM with no disks - but it is not what the person who enabled HA was expecting to buy.

Recovering from error state, once you have made the storage available or decided to restore:

Service impact possibleclear an HA service stuck in error state
set -euo pipefail
VMID=100

ha-manager set "vm:$VMID" --state disabled
# ... resolve the storage or restore the guest ...
ha-manager set "vm:$VMID" --state started

ha-manager status | grep "vm:$VMID"

Fencing: the prerequisite that is not optional

Fencing is the part that makes HA safe rather than merely automatic, and it is the part that gets treated as a detail.

The principle is not specific to Proxmox, and this course does not restate it

The one-sentence version, because it must be said here too: HA without working fencing is not high availability, it is a mechanism for putting two writers on one disk. If the CRM cannot be certain the old node has stopped, starting the guest elsewhere means two live instances writing to the same image, and a filesystem subjected to that does not survive it.

Proxmox implements self-fencing through the watchdog. The prerequisites:

RequirementWhyCheck
A watchdog device existsNothing reboots a wedged node without itls -l /dev/watchdog*
watchdog-mux is runningIt is what arms the watchdog for the LRMsystemctl status watchdog-mux
Hardware watchdog configured, ideallysoftdog depends on the kernel it is meant to catch/etc/default/pve-ha-manager
Corosync has redundant linksA single-link partition is a fencing eventcorosync-cfgtool -s

The other prerequisites

Three nodes, or two plus a QDevice. Quorum needs a majority. A two-node cluster has no majority after one failure, so the survivor cannot safely act; the QDevice supplies the third vote. Covered in quorum and QDevice.

Capacity for one node’s workload on the survivors. HA cannot start what does not fit. A cluster at 90% utilisation has HA configured and not available.

The guest’s network must exist on every candidate node. A bridge named vmbr1 on pve-01 and absent on pve-03 means recovery onto pve-03 produces a running guest with no network - which is often worse than a stopped one, because monitoring sees it as up.

No node-pinning devices. PCI passthrough, a mapped USB device, a dev[n] entry on a container: all of these pin the guest to hardware. HA will start the guest without the device unless a node-affinity rule prevents it.

A readiness check that can fail

Run this before enabling HA on anything, and after any storage or network change. It is deliberately written so that each check either passes or prints a specific failure.

Read-only / SafeHA readiness for one guest
set -euo pipefail
VMID=100
NODES='pve-01 pve-02 pve-03'

echo '--- quorum ---'
pvecm status | grep -E 'Quorate|Expected votes|Total votes'

echo '--- storage backing this guest ---'
# Storage IDs referenced by any disk line in the guest config.
STORES=$(qm config "$VMID" \
| grep -oE '^(scsi|virtio|sata|ide|efidisk|tpmstate)[0-9]+: [A-Za-z0-9_.-]+:' \
| awk '{print $2}' | tr -d ':' | sort -u)
for STORE in $STORES; do
# type and shared, straight from the storage definition
printf '  %-16s ' "$STORE"
pvesh get "/storage/$STORE" --output-format yaml \
  | grep -E '^(type|shared):' | tr '\n' ' '
printf '\n'
done

echo '--- bridges present on every node ---'
for BR in $(qm config "$VMID" | grep -oE 'bridge=[a-z0-9]+' | cut -d= -f2 | sort -u); do
for N in $NODES; do
  ssh -o BatchMode=yes "root@$N" "ip link show $BR >/dev/null 2>&1" \
    && printf '  %s on %s OK\n' "$BR" "$N" \
    || printf '  %s MISSING on %s\n' "$BR" "$N"
done
done

echo '--- node pinning ---'
qm config "$VMID" | grep -E '^(hostpci|usb)[0-9]+:' \
&& echo '  WARNING: passthrough pins this guest to specific hardware' \
|| echo '  no passthrough'

echo '--- fencing ---'
for N in $NODES; do
printf '  %s watchdog: ' "$N"
ssh -o BatchMode=yes "root@$N" 'ls /dev/watchdog 2>/dev/null || echo MISSING'
done

Four failure classes, four specific messages. That is what distinguishes a readiness check from ha-manager status, which tells you HA is configured and nothing about whether it would work.

One nuance in reading the storage output: shared is absent from the definition of backends that are inherently shared - rbd, cephfs, nfs, cifs all are, by construction. An absent shared line on a dir, lvmthin or zfspool entry is the failure; an absent one on rbd is normal. Read the type first, then the flag.

Knowledge check

Knowledge check · 5 questions

  1. Q1. A VM on local LVM-thin storage is added to HA management. Its node fails. What happens?

  2. Q2. Why is a hardware watchdog preferred over the softdog kernel module for HA fencing?

  3. Q3. Which of these are genuine prerequisites for HA to recover a guest? Select all that apply.

  4. Q4. A guest on local ZFS with pvesr replication to another node can be recovered by HA, but with data loss bounded by the replication interval.

  5. Q5. What is the danger of setting shared=1 on a directory storage that is not actually shared?

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