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.
Adding a node to a Proxmox cluster is one command and is nearly
impossible to get wrong. Removing one is a sequence, most of the steps
are irreversible, and doing them out of order can cost you quorum, Ceph
data, or both.
The asymmetry is not an oversight. pvecm delnode removes an identity
from a distributed system that other nodes have been coordinating with,
and that identity cannot come back — which puts a lot of weight on
getting everything off the node before you run it.
The order, and why it is this order
Take the node out of HA scheduling so nothing is placed on it
while you work.
Move every guest off, HA-managed and not.
Remove its Ceph daemons — OSDs first and one at a time, then the
manager, then the monitor.
Remove any storage that only exists on this node from the cluster
storage configuration.
Shut the node down and confirm the cluster is quorate without it.
Run pvecm delnode from a surviving node.
Ensure the removed node never boots onto the cluster network
again.
Sanitise the disks, then dispose of or repurpose the hardware.
Each step assumes the previous ones. Steps 3 and 6 are the two that cause
real damage when reordered.
Step 1–2: evacuate
Service impact possiblestop new placement, then move what is there— Maintenance mode migrates HA-managed guests off in a controlled order and stops the CRM placing anything new. Non-HA guests are not covered and must be migrated explicitly.
NODE=pve03
ha-manager crm-command node-maintenance enable "$NODE"
ha-manager status
# Anything still on the node, HA-managed or not:
pvesh get /nodes/"$NODE"/qemu --output-format json | grep -o '"vmid":[0-9]*'
pvesh get /nodes/"$NODE"/lxc --output-format json | grep -o '"vmid":[0-9]*'
Service impact possiblemigrate the remainder— Live-migrates a VM to another node. Guests on node-local storage cannot live-migrate and need an offline migration with a storage move, which copies the disk and takes proportionally longer.
VMID=142
TARGET=pve01
qm migrate "$VMID" "$TARGET" --online
# For a guest on local storage:
# qm migrate "$VMID" "$TARGET" --with-local-disks
The check that matters before continuing is that the node holds nothing
at all — not just nothing running. A stopped VM, an ISO nobody
remembers, a container template, a backup written to local are all
data that disappears with the node.
Read-only / Safewhat is still on this node's local storage?— Read-only. Run this on the node being decommissioned. The first command lists its storages; the loop prints the contents of each, which is where a forgotten ISO, template or local backup shows up.
pvesm status
for STORE in $(pvesm status --enabled 1 | awk 'NR>1 {print $1}'); do
echo "== $STORE"
pvesm list "$STORE"
done
Step 3: Ceph, if the node runs it
This is the step where impatience destroys data.
A Proxmox node running Ceph typically hosts OSDs, and often a monitor and
a manager. Each has to be removed in a way that lets the cluster
re-establish its redundancy first.
Read-only / Safewhat does this node run?— Read-only. Establishes the daemons on the node and the current health. Do not start removing anything while health is not HEALTH_OK for reasons unrelated to this work.
NODE=pve03
ceph -s
ceph osd tree
ceph mon dump
ceph mgr dump | head -20
Data-loss riskremove one OSD, then wait— Marking an OSD out triggers rebalancing of its data onto the remaining OSDs. Destroying it before the rebalance completes removes a copy the cluster is still relying on. One OSD at a time, and wait for HEALTH_OK between each.
OSD_ID=7
ceph osd out "$OSD_ID"
# Wait for the rebalance. Do not proceed until this reports HEALTH_OK
# and no PGs are degraded or backfilling.
watch -n 10 ceph -s
pveceph osd destroy "$OSD_ID"
Once the OSDs are gone, remove the manager and then the monitor:
Cluster-wide riskremove the manager, then the monitor— Monitors form their own quorum. Removing one changes the monitor count, so check that an odd number remains and that quorum survives before and after.
NODE=pve03
pveceph mgr destroy "$NODE"
ceph mon stat
pveceph mon destroy "$NODE"
ceph mon stat
Monitors need their own majority. Going from three monitors to two leaves
a configuration that cannot tolerate a single failure — so a
decommission that reduces the monitor count should be paired with
promoting a monitor elsewhere, ideally before the removal rather than
after.
Step 4–5: storage, shutdown, quorum
Remove storage definitions that only pointed at this node. A definition
restricted to a removed node is a stale entry that produces confusing
errors later; a shared definition should keep working and is worth
verifying rather than assuming.
Configuration changeclean up node-restricted storage— Removes a storage definition, or narrows its node list. This changes cluster configuration, so it is replicated immediately; it does not delete any data.
cat /etc/pve/storage.cfg
# Drop a node from a storage's node restriction:
pvesm set local-zfs-pve03 --nodes pve01,pve02
# Or remove the definition entirely:
pvesm remove local-zfs-pve03
Then shut the node down and confirm the cluster is healthy without it:
Read-only / Safeis the cluster fine without this node?— Read-only. Run from a surviving node after the target is powered off. Expected votes drops by one only after delnode; before it, the cluster still expects this node to vote.
pvecm status
pvecm nodes
ha-manager status
Step 6: pvecm delnode
Cluster-wide riskremove the node from the cluster— Removes the node from corosync and from the cluster configuration, cluster-wide and immediately. Not reversible. The target node must be powered off when this runs.
NODE=pve03
pvecm delnode "$NODE"
pvecm status
pvecm nodes
The node must be off when this runs. Removing a node that is still
running leaves it believing it is a cluster member while the cluster has
forgotten it — and what happens next is the subject of the failure
section below.
After removal, the node’s directory under /etc/pve/nodes/ remains. It
holds that node’s guest configurations and its host.fw, and Proxmox
keeps it deliberately so a mistake is recoverable. Once you are certain
the node is gone for good, it can be removed:
Destructiveclean up the leftover configuration directory— Deletes the removed node's configuration from pmxcfs, cluster-wide. Verify the directory contains no guest configuration you still need: these are the last copies.
NODE=pve03
ls -la /etc/pve/nodes/"$NODE"/
ls -la /etc/pve/nodes/"$NODE"/qemu-server/ /etc/pve/nodes/"$NODE"/lxc/ 2>/dev/null
# Only after confirming the above is empty of anything you need:
rm -r /etc/pve/nodes/"$NODE"
Step 7–8: keep it gone, then sanitise
Make sure it cannot come back. Disconnect it from the cluster
network, or wipe it, before it is powered on again for any reason.
Then sanitise the disks. The right method depends on the media, and
the wrong method is a common finding.
Media
Method
Notes
SATA/SAS SSD
ATA Secure Erase, or the drive’s sanitize command
Overwriting is unreliable on flash: wear levelling means the blocks you write are not the blocks that held the data
NVMe SSD
nvme format with a secure-erase setting
The controller erases including over-provisioned blocks
Self-encrypting drive
Crypto-erase — destroy the key
Instant, and complete, because the ciphertext becomes unrecoverable
Spinning disk
Multi-pass overwrite, or degauss
Overwriting genuinely works here
Any, high-assurance
Physical destruction
The only method that needs no trust in the firmware
ZFS or LUKS encrypted at rest
Destroy the key material
The simplest correct answer, if it was encrypted from the start
The strongest position is to decide this at build time rather than at
disposal time. A node whose pool was created with ZFS native encryption
is sanitised by destroying the key, which takes seconds, works regardless
of media, and is verifiable.
The mixed-generation cluster
A refresh means new nodes and old nodes coexisting for weeks. Three
things need attention.
CPU model and live migration. A guest with cpu: host gets the
host’s full feature set, and cannot migrate to a node whose CPU lacks a
feature it is using. In a mixed cluster that means new guests started on
new hardware cannot move to the old nodes — which is fine until you need
to evacuate a new node. Set a common CPU model that all generations
support for anything that must migrate freely, and accept host only
where the guest is pinned to a hardware class deliberately.
Uneven capacity changes placement. HA and CRS place guests according
to available resources, so new larger nodes attract more guests. That is
usually desirable and it concentrates blast radius: losing one new node
now takes out more workload than losing one old node ever did. Check the
failure arithmetic after the first new node arrives rather than after the
last one.
Ceph across generations. Mixing OSD sizes changes CRUSH weighting,
and mixing device classes — spinning disks and NVMe in one pool — makes
the pool as slow as its slowest members for the placement groups that
land there. Plan the CRUSH rules alongside the hardware, not after it.
Read-only / Safewhat will and will not migrate?— Read-only. Lists the CPU type configured for each VM. Anything set to host is pinned to hardware compatible with where it started.
for VMID in $(qm list | awk 'NR>1 {print $1}'); do
printf '%s ' "$VMID"
qm config "$VMID" | grep -E '^cpu:' || echo 'cpu: (default kvm64)'
done
Common mistakes
pvecm delnode while the node is still running. The node keeps
believing it is a member. Power it off first.
Removing several OSDs at once. Concurrent rebalances can take
placement groups below min_size and stop I/O, or lose data on a
size=2 pool.
Not waiting for HEALTH_OK between OSD removals. The wait is the
procedure.
Decommissioning to two nodes without adding a QDevice. A two-node
cluster cannot survive a single failure.
Reducing monitors to two. Promote a replacement monitor before the
removal, not after.
Assuming the node is empty because nothing is running. Stopped
guests, ISOs, templates and local backups all vanish with it.
dd if=/dev/zero on an SSD as sanitisation. Wear levelling means
the data is still there.
Leaving the node on a shelf, configured. It gets powered on six
months later by someone who was not involved.
Forgetting cpu: host guests during a refresh. They cannot migrate
back to older hardware, which you discover while evacuating a new node.
Key takeaways
The order is evacuate, remove Ceph daemons, clean up storage, shut
down, delnode, keep it off the network, sanitise. Most steps are
irreversible.
OSDs come out one at a time with a wait for HEALTH_OK between each.
Concurrent rebalances are how a decommission becomes an outage.
The node must be powered off before pvecm delnode, and a removed node
must be reinstalled before it joins anything again.
A powered-on removed node can cause split-brain, and with HA enabled
can start a guest that is already running elsewhere.
Expected votes drop at delnode, not at shutdown. Complete each
removal before shutting down the next node.
/etc/pve/nodes/$NODE survives on purpose and holds the last copies of
that node’s guest configurations.
Sanitise according to the media. Encrypting at rest from day one turns
disposal into key destruction.
In a mixed-generation cluster, watch cpu: host guests, concentrated
blast radius on larger nodes, and CRUSH weighting across device
classes.
Knowledge check
Knowledge check · 4 questions
Q1. A node being decommissioned hosts four Ceph OSDs. What is the correct removal approach?
Q2. Six months after a decommission, the removed node is powered on while still connected to the cluster switch, with its old /etc/pve intact. A new node has since been added to the cluster. What is the worst realistic outcome?
Q3. Which of these are correct about sanitising the disks from a decommissioned node? Select all that apply.
Q4. A powered-off node still counts toward the cluster expected vote total until pvecm delnode runs, so shutting down several nodes before completing their removals can leave the cluster short of quorum.
Passing score: 75%. Answers are checked in this browser.