Proxmox VEXVIII · Maintenance & LifecycleUpgrades
The pveXtoY upgrade checker and the pre-upgrade gate
What you'll learn
- Run pve8to9 at the right points in an upgrade and read each result class correctly
- Clear the findings the checker raises, rather than acknowledging them
- Name the failure classes the checker does not cover and check them yourself
- Turn the output into a go/no-go decision with a stated rollback position
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
Proxmox ships a checker with every major upgrade. It is named for the
transition — pve7to8, pve8to9 — it is installed on the source version
before you need it, and it is the first command in Proxmox’s own
documented procedure.
It is also the single highest-value command in a major upgrade, because
it converts a category of failure that would otherwise appear halfway
through apt dist-upgrade on a production node into a list you can read
beforehand, on a node that is still working.
What it is
pve8to9 inspects the node and the cluster and reports on everything
Proxmox knows can break an 8-to-9 upgrade. It makes no changes by
default — it is a report, and every finding is yours to act on.
pve8to9
pve8to9 --full--full runs the extended set, including the slower checks. Use it: the
time saved by the short form is minutes, and the checks it skips are not
the unimportant ones.
Reading the output
Findings come in five classes and the correct response differs for each.
| Class | Meaning | What to do |
|---|---|---|
PASS | Checked, and fine | Nothing |
INFO | Informational context | Read it. Some INFO lines carry version numbers you need later |
SKIP | Not applicable to this node | Confirm the reason is what you expect |
WARN | Will not stop the upgrade; may change behaviour after it | Investigate every one, then decide |
FAIL | Will break the upgrade or the node afterwards | Clear it. This is a stop. |
# pve8to9 --full= CHECKING VERSION INFORMATION FOR PVE PACKAGES =
Checking for package updates..
PASS: all packages up-to-date
Checking proxmox-ve package version..
PASS: proxmox-ve package has version >= 8.4.0
= CHECKING CLUSTER HEALTH/SETTINGS =
PASS: systemd unit 'pve-cluster.service' is in state 'active'
PASS: Cluster Filesystem is quorate.
WARN: 1 nodes are offline!
= CHECKING HYPER-CONVERGED CEPH STATUS =
SKIP: no hyper-converged ceph setup detected!
= CHECKING CONFIGURED STORAGES =
PASS: storage 'local' enabled and active.
WARN: storage 'backup-nfs' enabled but not active!
= MISC CHECKS =
PASS: Resolved node IP '192.0.2.11' configured and active on single interface.
FAIL: There is only 3.1 GiB free space on '/'. 5 GiB is the minimum,
10 GiB or more is recommended.
INFO: Found 2 guest(s) with 'machine' set to a pinned version.
= SUMMARY =
TOTAL: 41
PASSED: 36
SKIPPED: 2
WARNINGS: 2
FAILURES: 1
ATTENTION: Please check the output for detailed information!Illustrative output
Clearing the common findings
Insufficient free space on /
The prerequisite is “at least 5 GB free disk space on the root mount
point, ideally more than 10 GB”. This is the most frequent FAIL and
the most dangerous to ignore, because running out of space partway
through dist-upgrade leaves the package database in a state that is
tedious to repair on a node that is no longer serving guests.
df -h /
du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -15
du -sh /var/cache/apt/archives /var/log/journal
proxmox-boot-tool kernel listapt autoclean
journalctl --vacuum-size=500M
apt autoremove --purgeIf old kernels are the consumer, remove one from the boot set with
proxmox-boot-tool kernel remove rather than deleting files from
/boot, which on a ZFS-root system is not where the booting kernels
live.
An offline node
A WARN about offline nodes is a FAIL in disguise for a cluster
upgrade. An upgrade performed while a node is down produces a cluster
where the absent node comes back on the old version, into a cluster that
has moved — and the version-skew tolerance during a major upgrade is
bounded and temporary, not indefinite.
Bring it back, or remove it from the cluster deliberately, before starting.
A storage configured but not active
An inactive storage during an upgrade is usually harmless in itself and is a signal worth chasing: either the storage is genuinely gone and the configuration is stale, or it is temporarily unreachable, in which case a guest referencing it will not start after the reboot.
pvesm status
cat /etc/pve/storage.cfgDisable a stale definition rather than deleting it, so the change is reversible during the window.
Ceph must be upgraded first
The documentation is explicit: “Hyper-converged Ceph: upgrade any Ceph
Quincy or Ceph Reef cluster to Ceph 19.2 Squid before you start the
Proxmox VE upgrade to 9.0.” Confirm with ceph --version before
proceeding.
This ordering is not a preference. Skipping it puts you in a combination Proxmox does not test, on a storage layer holding every running guest.
Old configuration formats and deprecated settings
The checker reports settings that PVE 9 handles differently — legacy
sources.list entries rather than deb822 .sources files, deprecated
storage options, guest configuration keys that changed meaning. Each of
these is a small, specific edit, and each is much cheaper before the
upgrade than as a surprise after it.
Where to run it, and when
Three points, and the third is the one people skip.
Before you touch anything. On every node. Findings differ per node — free space, local storage, pinned machine versions — and a cluster is ready when the last node is, not the first.
After each node upgrades, on the nodes still on the old version. The checker is cluster-aware, and running it mid-upgrade surfaces problems introduced by the mixed-version state.
After the whole cluster is done. The documentation asks for this explicitly, and it is the step that turns “the upgrade completed” into “the upgrade is correct”.
for NODE in pve01 pve02 pve03; do
echo "=== $NODE ==="
ssh "root@$NODE" 'pve8to9 --full' 2>&1 | tee "/root/pve8to9-$NODE.txt"
done
grep -c '^FAIL' /root/pve8to9-*.txtKeep those files. They are the pre-upgrade evidence, and comparing the post-upgrade run against them is how you show the window achieved what it set out to.
What the checker does not check
This is the section that matters most, because a clean run creates confidence proportional to how much you think it covered.
Your guests. The checker verifies the platform. It says nothing about whether the applications inside your VMs tolerate the reboot, whether a guest depends on a QEMU machine version that behaves differently under QEMU 11, or whether a container’s userspace works on the new kernel.
Your automation. Terraform providers, Ansible collections, Proxmoxer, custom scripts against the API — all pinned to an API surface that changes across a major version. Nothing checks these, and the symptom arrives at the next automated run rather than during the window.
Your backups. It does not verify that a restore works. The prerequisite is “a valid and tested backup of all VMs and CTs”, and “tested” is doing the work in that sentence. A restore drill before a major upgrade is the actual safety net; the checker is the gate.
Your monitoring and integrations. Metric server exports, notification targets, an external Ceph client, a PBS server on a version that may need its own upgrade first.
Hardware and firmware. A NIC that needs a firmware level for the new kernel, an HBA with a known issue, a BMC that needs updating. The 6.x-to-7.0 kernel move in PVE 9.2 makes this a live concern.
Your ability to get out. There is no rollback for a major upgrade of a running node. The way back is restore from backup, and the checker does not ask whether you could.
Common mistakes
- Running it once, on one node. Findings are per node, and a cluster is ready when the last node is.
- Treating
WARNas noise. Offline nodes and inactive storages are warnings that become failures after the reboot. - Skipping
--full. The checks it omits are not the unimportant ones. - Not running it after the upgrade. That run is what turns “completed” into “correct”.
- Reading
FAILURES: 0as “safe to proceed”. It means the platform is ready. Guests, automation, backups and firmware are separate questions. - Upgrading before Ceph. Explicitly documented as the wrong order, on the layer holding every guest.
- Running it on a node that has not applied PVE 8 updates. The checker itself is out of date.
- No restore drill. The checker is the gate; the tested backup is the safety net, and only one of them gets you out.
Key takeaways
pve8to9 --fullis the first command in Proxmox’s own upgrade procedure. It changes nothing and gates everything.- Five result classes.
FAILis a stop;WARNis an investigation;SKIPdeserves a glance at why. - Run it before, between nodes, and after. Capture the output as evidence.
- Clear findings rather than acknowledging them. Free space, offline nodes, inactive storages and Ceph ordering are the recurring four.
- Upgrade Ceph to Squid before starting PVE 9. Documented, and on the layer under every guest.
- It cannot see your guests, your automation, your backups or your firmware. Check those yourself.
- A major upgrade has no rollback. The checker finds problems while turning back is still free.
Knowledge check
Knowledge check · 4 questions
Q1. pve8to9 --full reports FAILURES: 0 on every node in a five-node cluster. What has this established?
Q2. Which findings should stop a major upgrade until they are cleared, rather than being acknowledged and passed? Select all that apply.
Q3. A hyper-converged Ceph cluster must be upgraded to Ceph 19.2 Squid before starting the Proxmox VE 9 upgrade, not after.
Q4. When should pve8to9 be run during a cluster upgrade?
Passing score: 75%. Answers are checked in this browser.