{"id":6132,"date":"2026-09-02T20:46:03","date_gmt":"2026-09-02T11:46:03","guid":{"rendered":"https:\/\/eternalsphere.net\/echoes\/?p=6132"},"modified":"2026-09-12T17:17:06","modified_gmt":"2026-09-12T08:17:06","slug":"hhljj86pchq4l2k","status":"publish","type":"post","link":"https:\/\/blog.eternalsphere.net\/index.php\/2026\/09\/02\/hhljj86pchq4l2k\/","title":{"rendered":"Proxmox VE 8 to 9: Post-Upgrade Audit After Hardware and Storage Migration"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Long-lived Proxmox VE installations often accumulate history.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A system may begin life on a rack server, later migrate to compact x86 hardware, change storage architecture, replace ZFS with LVM\/ext4, and still retain traces of older configurations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A major PVE upgrade can expose that history in logs and disk metadata.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The difficult part is not finding warnings.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The difficult part is deciding which warnings are still operationally relevant.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Confirm the PVE Stack<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Useful commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pveversion\npveversion -v\ncat \/etc\/os-release\nuname -a<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A fully upgraded PVE 9 system should consistently report:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PVE 9.x;<\/li>\n\n\n\n<li>Debian 13 Trixie;<\/li>\n\n\n\n<li>current Proxmox kernel;<\/li>\n\n\n\n<li>matching PVE package generation.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Check the Core PVE Services<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Review:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl is-system-running\nsystemctl --failed<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then inspect:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl status pve-cluster --no-pager\nsystemctl status pvedaemon --no-pager\nsystemctl status pveproxy --no-pager\nsystemctl status pvestatd --no-pager\nsystemctl status pvescheduler --no-pager\nsystemctl status qmeventd --no-pager<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For a standalone node, the absence of an active Corosync cluster is normal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cluster-related warnings should be interpreted according to whether clustering is actually configured.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Verify pmxcfs and <code>\/etc\/pve<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The PVE configuration filesystem is critical:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>findmnt \/etc\/pve\nls -la \/etc\/pve\nls -la \/etc\/pve\/nodes\/$(hostname)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A healthy standalone node should still have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>readable VM configuration;<\/li>\n\n\n\n<li>readable storage configuration;<\/li>\n\n\n\n<li>mounted <code>pmxcfs<\/code>;<\/li>\n\n\n\n<li>intact node directory.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Audit VM and Guest Agent State<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">List VMs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qm list<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inspect one VM:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qm status 101\nqm config 101<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If guest agent is enabled:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qm agent 101 ping<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A useful broader check is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>for id in $(qm list | awk 'NR&gt;1 &amp;&amp; $3==\"running\" {print $1}'); do\n    echo \"----- VM $id -----\"\n    agent=\"$(qm config \"$id\" | sed -n 's\/^agent:&#091;&#091;:space:]]*\/\/p')\"\n\n    if &#091; -z \"$agent\" ]; then\n        echo \"QEMU Guest Agent: not configured\"\n    elif qm agent \"$id\" ping &gt;\/dev\/null 2&gt;&amp;1; then\n        echo \"QEMU Guest Agent: PASS\"\n    else\n        echo \"QEMU Guest Agent: FAIL\"\n    fi\ndone<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Interpreting a One-Time Guest Agent Timeout<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A common startup sequence can look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>VM started\nguest-ping timeout\nguest-ping timeout\nguest-ping timeout\nforced stop\nVM restarted\nguest agent later responds normally<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is especially plausible when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PVE itself has just booted;<\/li>\n\n\n\n<li>an external disk enclosure is still becoming ready;<\/li>\n\n\n\n<li>several VMs start simultaneously;<\/li>\n\n\n\n<li>storage I\/O is temporarily saturated;<\/li>\n\n\n\n<li>a large VM resides on slower or externally attached storage.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If subsequent checks show:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>QEMU Guest Agent: PASS<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and the VM later completes a long backup successfully, then the historical timeout can be classified as a one-time startup condition.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A historical error does not remain a current fault indefinitely.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Storage Layouts Can Be More Complex Than PVE&#8217;s GUI Suggests<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Consider a storage definition:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dir: local\n    path \/var\/lib\/vz\n    content iso,backup,snippets,vztmpl,images,rootdir<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now consider that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/var\/lib\/vz<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">resides on the root filesystem, while:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/var\/lib\/vz\/images<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is a separate 7 TB filesystem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pvesm status<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">may report the capacity of <code>\/var\/lib\/vz<\/code> itself, while VM images physically reside on the nested mount.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verify with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>findmnt -T \/var\/lib\/vz\nfindmnt -T \/var\/lib\/vz\/images\ndf -hT \/var\/lib\/vz \/var\/lib\/vz\/images<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This can produce:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/var\/lib\/vz         \u2192 root filesystem\n\/var\/lib\/vz\/images  \u2192 separate large ext4 filesystem<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That design is unusual but valid if intentional and stable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The important point is that the PVE GUI&#8217;s <code>local<\/code> capacity may not represent the actual VM-image filesystem.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Old ZFS Signatures After Storage Migration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A disk that previously belonged to a ZFS pool may still contain ZFS labels after being repurposed for LVM.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wipefs -n \/dev\/sdb\nwipefs -n \/dev\/sdb1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">may show:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>zfs_member<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">while:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>blkid \/dev\/sdb1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">shows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TYPE=\"LVM2_member\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pvs\nvgs\nlvs<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">confirm that the partition is actively used by LVM.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>zpool status<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">returns:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>no pools available<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then the old ZFS labels are historical metadata.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Why Old ZFS Labels Should Usually Be Left Alone<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It may be tempting to remove stale signatures with <code>wipefs<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is rarely worth the risk on a live disk containing several terabytes of VM data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The operational benefit is close to zero.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The potential cost of an incorrect metadata operation is very high.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A safer classification is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Historical storage metadata\nInactive\nKnown\nNo current operational effect\nLeave untouched<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is preferable to destructive cleanup for cosmetic reasons.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">9. ACPI and Intel Graphics Warnings on Headless Hosts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After migration to compact hardware, kernel logs may contain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ACPI BIOS Error\nAE_ALREADY_EXISTS<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and Intel graphics messages such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Failed to probe lspcon\nCannot find any crtc or sizes\ncrtc active state doesn't match with hw state<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On a headless virtualization host, these messages may simply reflect firmware\/display initialization that does not match the Linux graphics driver&#8217;s expectations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>no display functionality is required;<\/li>\n\n\n\n<li>the server boots successfully;<\/li>\n\n\n\n<li>VMs run normally;<\/li>\n\n\n\n<li>the errors occur only during boot;<\/li>\n\n\n\n<li>no GPU hang appears later;<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">then disabling i915 or adding ACPI kernel parameters solely to suppress log messages is usually unjustified.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">10. Verify That Warnings Do Not Recur<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A powerful check is to inspect only the period after startup stabilization:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>journalctl -b --since '30 minutes after boot' --no-pager | \\\ngrep -Ei \\\n'qga command failed|guest-ping.*timeout|i915.*(error|fail|hang)|ACPI.*Error|I\/O error|EXT4-fs error|corruption|OOM|out of memory'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the output is empty, that provides stronger evidence than merely counting boot-time warnings.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">11. Validate PVE-to-PBS Backup<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A successful backup cycle proves several components simultaneously:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PVE scheduler\nVM snapshot handling\nQEMU integration\nnetwork path\nPBS authentication\nTLS\nPBS datastore\ndisk read path\nbackup client<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A completed task marked <code>OK<\/code> is strong evidence that the virtualization and backup stack survived the upgrade successfully.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">12. Final Health Criteria<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A migrated PVE host can reasonably be classified as healthy when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PVE services are active;<\/li>\n\n\n\n<li><code>\/etc\/pve<\/code> is healthy;<\/li>\n\n\n\n<li>VM inventory is intact;<\/li>\n\n\n\n<li>running guests respond normally;<\/li>\n\n\n\n<li>guest agents work after startup;<\/li>\n\n\n\n<li>storage mounts are correct;<\/li>\n\n\n\n<li>no active ZFS pool conflict exists;<\/li>\n\n\n\n<li>no I\/O or filesystem error persists;<\/li>\n\n\n\n<li>PVE-to-PBS backup completes successfully;<\/li>\n\n\n\n<li>repository and package state are correct;<\/li>\n\n\n\n<li>no recurring kernel or service error remains after startup.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Historical firmware warnings and stale storage signatures do not invalidate that conclusion.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A mature PVE installation often contains traces of earlier hardware, storage, and operating decisions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Those traces should be classified, not automatically erased.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A stable system with:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>known benign ACPI messages;<\/li>\n\n\n\n<li>inactive historical ZFS signatures;<\/li>\n\n\n\n<li>a one-time VM startup timeout;<\/li>\n\n\n\n<li>unusual but intentional storage mounts;<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">can still be fully healthy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The more useful objective is not a perfectly empty log.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The more useful objective is a system with <strong>no unresolved operational fault<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Long-lived Proxmox VE installations often accumulate history. A system may begin life on a rack server, later migrate to compact x86 hardware, change storage architecture, replace ZFS with LVM\/ext4, and still retain traces of older configurations. A major PVE upgrade can expose that history in logs and disk metadata. &hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[118],"tags":[241,332],"class_list":["post-6132","post","type-post","status-publish","format-standard","hentry","category-tm5418kixf8ipqv","tag-proxmox","tag-storage"],"_links":{"self":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6132","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/comments?post=6132"}],"version-history":[{"count":1,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6132\/revisions"}],"predecessor-version":[{"id":6133,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6132\/revisions\/6133"}],"wp:attachment":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/media?parent=6132"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/categories?post=6132"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/tags?post=6132"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}