{"id":2934,"date":"2026-11-02T10:40:08","date_gmt":"2026-11-02T10:40:08","guid":{"rendered":"https:\/\/hostry.com\/blog\/?p=2934"},"modified":"2026-11-02T10:40:10","modified_gmt":"2026-11-02T10:40:10","slug":"upgrade-ubuntu-24-04-to-26-04","status":"publish","type":"post","link":"https:\/\/hostry.com\/blog\/upgrade-ubuntu-24-04-to-26-04\/","title":{"rendered":"Upgrade Ubuntu 24.04 to 26.04 on a VPS: What Breaks, How to Recover"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-cover.webp\" alt=\"Upgrade Ubuntu 24.04 to 26.04 on a VPS: backup, do-release-upgrade over SSH with a spare sshd on port 1022, then post-upgrade checks\" class=\"wp-image-2926\" srcset=\"https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-cover.webp 1200w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-cover-300x169.webp 300w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-cover-1024x576.webp 1024w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-cover-450x253.webp 450w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-cover-768x432.webp 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted\" style=\"font-size:14px\"><em><strong>A stock Ubuntu 24.04 server upgrades in place with sudo do-release-upgrade over SSH once two blockers are cleared: the upgrader refuses to run without cgroup v2, or with MySQL accounts on mysql_native_password while that plugin is disabled. A heavily customized server is usually better rebuilt. Either way, start only with an off-server backup you have restored once.<\/strong><\/em><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Canonical enabled upgrades to 26.04.1 LTS on September 29, 2026, and Ubuntu Server users can start whenever they are ready. To <strong>upgrade Ubuntu 24.04 to 26.04<\/strong> safely, the order matters more than the command. The usual way to strand a VPS is to run the upgrader from your only SSH window with port 1022 closed: the connection drops while dpkg is unpacking, and the spare sshd the upgrader started cannot be reached.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For a server with years of hand edits, a fresh <strong><a href=\"https:\/\/hostry.com\/products\/vps\/\">KVM VPS with root access<\/a><\/strong> and a data migration is often less risk than an in-place upgrade. Commands below were checked on November 2, 2026 against the release notes, the Ubuntu Server docs and the code of the 26.04 upgrader (version 26.04.27).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Upgrade Ubuntu 24.04 to 26.04 in place or rebuild on a new VPS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The upgrader can undo very little. Its source shows that an abort before packages install puts your APT sources back, but once dpkg has started, the only recovery it attempts is <span class=\"highlighted\">dpkg &#8211;configure -a<\/span>. do-release-upgrade has no downgrade option; returning to 24.04 means restoring from backup.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Your server<\/th><th>Upgrade in place<\/th><th>Rebuild and migrate<\/th><\/tr><\/thead><tbody><tr><td>Packages only from the Ubuntu archive, a few services<\/td><td>Good fit, one maintenance window<\/td><td>More work than the server needs<\/td><\/tr><tr><td>Docker or LXC host still booted with cgroup v1 or hybrid<\/td><td>Only after switching to cgroup v2 and rebooting; the upgrader refuses otherwise<\/td><td>Starts on cgroup v2 with nothing to switch<\/td><\/tr><tr><td>Several PPAs, vendor repos or keys added with apt-key<\/td><td>Each one needs a 26.04 suite and a signed-by keyring<\/td><td>Add back only the repos you still use<\/td><\/tr><tr><td>MySQL accounts on mysql_native_password, or RabbitMQ<\/td><td>Upgrader stops until you fix them<\/td><td>Fix accounts during the dump and import<\/td><\/tr><tr><td>No restore you have actually tested<\/td><td>Do not start<\/td><td>The old VPS stays untouched as the fallback<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A rebuild means restoring data onto a new VPS and switching DNS once it passes your checks, while the old server stays a working rollback during the overlap.<\/p>\n\n\n\n<aside class=\"hostry-author-note\" style=\"margin:26px 0;padding:16px 20px 14px;background:#fbf7ef;border-left:3px solid #eea416;border-radius:0 10px 10px 0;font-size:15px;line-height:1.6;color:#2b2f3a\"><div style=\"font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#b07a06;margin:0 0 6px\">From the engineer<\/div><p style=\"margin:0 0 12px\">If a server has already been through two in-place release upgrades, I would rebuild it. Every in-place upgrade carries leftovers forward: configs nobody remembers editing, packages nobody remembers installing. A fresh 26.04 VPS plus a restore is the cheapest moment to drop them.<\/p><div style=\"display:flex;align-items:center;gap:10px;font-size:13px;color:#5b6170\"><span style=\"display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;background:#11235e;color:#fff;font-size:12px;font-weight:700;flex:none\">SY<\/span><span><strong style=\"color:#11235e\">Stas Yantselovskiy<\/strong> \u00b7 System administrator &amp; DevOps engineer, Hostry<\/span><\/div><\/aside>\n\n\n\n<h2 class=\"wp-block-heading\">Ubuntu 26.04 upgrade problems on a server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The list draws on the <strong><a href=\"https:\/\/documentation.ubuntu.com\/release-notes\/26.04\/summary-for-lts-users\/\" target=\"_blank\" rel=\"noopener\">26.04 release notes summary for users coming from 24.04<\/a><\/strong> and the upgrader&#8217;s own checks. Test your application against the new PHP, Python and MySQL on a copy of the server first.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"800\" src=\"https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-blockers.webp\" alt=\"Three checks do-release-upgrade enforces before upgrading Ubuntu 24.04 to 26.04: cgroup v2, MySQL accounts on mysql_native_password and RabbitMQ feature flags, with the message each one prints\" class=\"wp-image-2936\" srcset=\"https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-blockers.webp 1200w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-blockers-300x200.webp 300w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-blockers-1024x683.webp 1024w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-blockers-450x300.webp 450w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-blockers-768x512.webp 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><figcaption>The three blockers the 26.04 upgrader checks for and the message it stops with; pre-flight steps 5 to 7 show how to clear each one<\/figcaption><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Ubuntu 26.04 and cgroup v1 with Docker<\/strong>: systemd 259 dropped the legacy and hybrid hierarchies, and the upgrader aborts with &#8220;Cannot upgrade without unified cgroupv2 hierarchy&#8221; (pre-flight step 5 has the check). The <strong><a href=\"https:\/\/docs.docker.com\/engine\/containers\/runmetrics\/\" target=\"_blank\" rel=\"noopener\">Docker runtime metrics docs<\/a><\/strong> list cgroup v2 support from Docker 20.10, with containerd 1.4 and runc 1.0.0-rc91 or later. Monitoring agents reading v1 paths need updates too.<\/li><li>sudo-rs replaces sudo, the original is renamed sudo.ws, and sudo-ldap is gone, so LDAP users move to PAM. Ubuntu Server&#8217;s sudo-rs reference adds that sudoreplay is unsupported and that the PAM password prompt breaks Expect scripts waiting for &#8220;[sudo] password for&#8221;.<\/li><li>Core utilities come from rust-coreutils; the GNU tools stay available with a gnu prefix.<\/li><li>OpenSSH moves from 9.6p1 to 10.2p1. DSA keys stop working, and sshd no longer reads ~\/.pam_environment, so variables set there disappear from SSH sessions.<\/li><li>Scripts and provisioning roles that call apt-key fail, because the command no longer exists.<\/li><li>Python 3.14 replaces 3.12; rebuild virtual environments.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Service<\/th><th>26.04 version<\/th><th>What stops working<\/th><\/tr><\/thead><tbody><tr><td>MySQL<\/td><td>8.4 LTS (from 8.0)<\/td><td>Accounts on mysql_native_password are locked out; the upgrader blocks until you fix them (pre-flight step 6)<\/td><\/tr><tr><td>PHP<\/td><td>8.5 (from 8.3)<\/td><td>Per PHP&#8217;s 8.5 migration guide, the disable_classes INI setting is removed, and zend_extension=opcache.so now emits a warning because OPcache is always built in<\/td><\/tr><tr><td>PostgreSQL<\/td><td>18 packages<\/td><td>Nothing breaks at once; your cluster stays on version 16 until you migrate it<\/td><\/tr><tr><td>Dovecot<\/td><td>2.4.2<\/td><td>The 2.3 configuration format; follow Dovecot&#8217;s 2.3 to 2.4 guide<\/td><\/tr><tr><td>Postfix<\/td><td>3.10, no chroot by default<\/td><td>Chroot settings in master.cf need review, since only limited chroot support remains<\/td><\/tr><tr><td>Squid<\/td><td>7.7 (7.2 at release)<\/td><td>The proxy will not start while Ident, mcast_miss_* or cache_object:\/\/ remain in squid.conf<\/td><\/tr><tr><td>Samba AD DC<\/td><td>new packaging<\/td><td>Domain controller functions, unless samba-ad-dc is installed before the upgrade<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">HAProxy 3.2 and OpenLDAP also have listed config changes. For PostgreSQL, <span class=\"highlighted\">pg_lsclusters<\/span> shows the major version of each cluster. <span class=\"highlighted\">sudo pg_upgradecluster 16 main<\/span> moves it to the newest installed version, gives the 16 cluster an unused port and keeps it until you drop it. Give that its own window and a fresh dump.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pre-flight checklist before do-release-upgrade<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"800\" src=\"https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-upgrade-flow.webp\" alt=\"Ubuntu 24.04 to 26.04 upgrade flow on a VPS: decide, pre-flight checks, do-release-upgrade over SSH with spare sshd on port 1022, post-flight checks, and recovery or rebuild from backup\" class=\"wp-image-2929\" srcset=\"https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-upgrade-flow.webp 1200w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-upgrade-flow-300x200.webp 300w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-upgrade-flow-1024x683.webp 1024w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-upgrade-flow-450x300.webp 450w, https:\/\/hostry.com\/blog\/wp-content\/uploads\/2026\/11\/upgrade-ubuntu-24-04-to-26-04-upgrade-flow-768x512.webp 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><figcaption>Where each check fits: the blockers the upgrader enforces sit before the upgrade, and the recovery path starts from the backup taken in step 1.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>1. Back up off the server, then prove you can restore<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo tar czf ~\/etc-noble.tar.gz \/etc\nsudo chown deploy: ~\/etc-noble.tar.gz &amp;&amp; chmod 600 ~\/etc-noble.tar.gz\napt-mark showmanual &gt; ~\/manual-packages.txt\nsudo -u postgres pg_dumpall &gt; ~\/pg-all.sql                       # if PostgreSQL runs here\nsudo mysqldump --all-databases --single-transaction &gt; ~\/mysql-all.sql   # if MySQL runs here\nrsync -a ~\/etc-noble.tar.gz ~\/manual-packages.txt ~\/*.sql deploy@backup.example.net:web1\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">(Put your own login and backup host in place of <span class=\"highlighted\">deploy<\/span> and <span class=\"highlighted\">backup.example.net<\/span>, and your server&#8217;s address wherever <span class=\"highlighted\">203.0.113.10<\/span> appears.) Add application data and uploads to the same copy. The check is a restore: import the dumps into a scratch server and list the tarball with <span class=\"highlighted\">tar tzf<\/span>.<\/p>\n\n\n\n<aside class=\"hostry-author-note\" style=\"margin:26px 0;padding:16px 20px 14px;background:#fbf7ef;border-left:3px solid #eea416;border-radius:0 10px 10px 0;font-size:15px;line-height:1.6;color:#2b2f3a\"><div style=\"font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#b07a06;margin:0 0 6px\">From the engineer<\/div><p style=\"margin:0 0 12px\">Of the whole checklist, the step I would never skip is the test restore. Put the backup on a spare VPS and start the main service there before you touch the live server. Until then you only know that an archive exists.<\/p><div style=\"display:flex;align-items:center;gap:10px;font-size:13px;color:#5b6170\"><span style=\"display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;background:#11235e;color:#fff;font-size:12px;font-weight:700;flex:none\">SY<\/span><span><strong style=\"color:#11235e\">Stas Yantselovskiy<\/strong> \u00b7 System administrator &amp; DevOps engineer, Hostry<\/span><\/div><\/aside>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>2. Finish 24.04 updates and reboot<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt full-upgrade -o APT::Get::Always-Include-Phased-Updates=true\nls \/run\/reboot-required 2&gt;\/dev\/null &amp;&amp; sudo reboot\napt list --upgradable<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The last command should print only &#8220;Listing&#8230;&#8221;. Otherwise the 24.04 upgrader stops with &#8220;Please install all available updates for your release before upgrading.&#8221; It also refuses to start after an unrebooted kernel or libc update.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>3. Free disk space on \/ and \/boot<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>df -h \/ \/boot\nsudo apt autoremove --purge &amp;&amp; sudo apt clean<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ubuntu&#8217;s server guide warns the download can run to several gigabytes. The upgrader stops before installing anything if \/ or \/boot is short.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>4. Third-party repositories and old apt-key keys<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>grep -rh -E \"^(URIs:|deb )\" \/etc\/apt\/sources.list \/etc\/apt\/sources.list.d\/ 2&gt;\/dev\/null | sort -u\nls -l \/etc\/apt\/trusted.gpg \/etc\/apt\/trusted.gpg.d\/ 2&gt;\/dev\/null\nsudo apt update 2&gt;&amp;1 | grep -i \"legacy trusted.gpg\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These commands only inspect; the upgrader itself disables PPAs and vendor repositories, leaves them disabled afterwards and rewrites <span class=\"highlighted\">.list<\/span> files as deb822 <span class=\"highlighted\">.sources<\/span>. It carries over a PPA key from <span class=\"highlighted\">trusted.gpg.d<\/span> when the file names match, but keys in <span class=\"highlighted\">\/etc\/apt\/trusted.gpg<\/span> stay behind, and 26.04 has no <span class=\"highlighted\">apt-key<\/span>. Check that each vendor publishes a <span class=\"highlighted\">resolute<\/span> suite; Docker does.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To fix a flagged repository, follow the DEPRECATION section of the apt-key(8) man page: fetch the vendor&#8217;s key again into <span class=\"highlighted\">\/etc\/apt\/keyrings\/<\/span>, the location APT has recommended since 2.4, and point the stanza at it with <span class=\"highlighted\">Signed-By:<\/span>. With repo.example.com as the vendor:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -fsSL https:\/\/repo.example.com\/key.asc | sudo tee \/etc\/apt\/keyrings\/example-repo.asc &gt; \/dev\/null\n\n# \/etc\/apt\/sources.list.d\/example-repo.sources\nTypes: deb\nURIs: https:\/\/repo.example.com\/ubuntu\nSuites: noble\nComponents: main\nSigned-By: \/etc\/apt\/keyrings\/example-repo.asc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keep the file world-readable, since the <span class=\"highlighted\">_apt<\/span> user has to read it. The step passes when <span class=\"highlighted\">apt update<\/span> no longer prints &#8220;Key is stored in legacy trusted.gpg keyring&#8221;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>5. Confirm the server boots on cgroup v2<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>stat -fc %T \/sys\/fs\/cgroup\/\ngrep -o \"systemd.unified_cgroup_hierarchy=[01]\" \/proc\/cmdline\ngrep -rn unified_cgroup_hierarchy \/etc\/default\/grub \/etc\/default\/grub.d\/ 2&gt;\/dev\/null<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You want <span class=\"highlighted\">cgroup2fs<\/span> from the first command and no output from the other two. <span class=\"highlighted\">tmpfs<\/span> means a legacy or hybrid hierarchy, usually forced years ago for an old Docker setup. Remove the parameter from GRUB, run <span class=\"highlighted\">sudo update-grub<\/span>, reboot, and let your containers run on cgroup v2 for a few days first.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>6. Find MySQL accounts that would be locked out<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mysql -e \"SELECT user, host FROM mysql.user WHERE plugin = 'mysql_native_password';\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">An empty result passes. With MySQL running, any row stops the 26.04 upgrader with &#8220;Unable to upgrade MySQL&#8221; unless the plugin is enabled in the server config. The release notes fix is <span class=\"highlighted\">ALTER USER &#8216;app&#8217;@&#8217;localhost&#8217; IDENTIFIED WITH caching_sha2_password BY &#8216;new-password&#8217;;<\/span>, which resets the password, so update the app config in the same window. Setting <span class=\"highlighted\">mysql_native_password=ON<\/span> under <span class=\"highlighted\">[mysqld]<\/span> in <span class=\"highlighted\">\/etc\/mysql\/mysql.conf.d\/mysqld.cnf<\/span> also passes the check, but only buys time until MySQL 9.7.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>7. Only if RabbitMQ runs here: enable its feature flags<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo rabbitmqctl list_feature_flags\nsudo rabbitmqctl enable_feature_flag all<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The upgrader reads the same list and stops with &#8220;Unable to upgrade RabbitMQ&#8221; unless the 3.13 flags RabbitMQ 4 needs, such as <span class=\"highlighted\">stream_filtering<\/span>, are enabled. 24.04 ships 3.12, so the <strong><a href=\"https:\/\/discourse.ubuntu.com\/t\/ubuntu-server-gazette-issue-12-upgrading-rabbitmq-across-ubuntu-releases\/77271\" target=\"_blank\" rel=\"noopener\">Ubuntu Server Gazette guide to upgrading RabbitMQ<\/a><\/strong> installs 3.13 from a canonical-server PPA first. Run <span class=\"highlighted\">enable_feature_flag all<\/span> again once 3.13 is running.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>8. Prepare a second way in<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>command -v screen || sudo apt install screen\nsudo ufw allow from 198.51.100.7 to any port 1022 proto tcp\nsudo ufw status numbered\nsudo passwd deploy\nsudo sshd -T | grep -i ^passwordauthentication<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here 198.51.100.7 is your workstation&#8217;s IP. The upgrader re-runs itself inside GNU screen when screen is installed and starts a spare sshd on port 1022. A firewall in front of the VPS, such as the built-in one in the Hostry control panel, needs the same rule. Then open a second SSH session and leave it idle.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If both SSH paths die, the fallback is the VNC console in the Hostry control panel. It shows the server&#8217;s own login, so a key-only account needs the password <span class=\"highlighted\">passwd<\/span> sets. The <span class=\"highlighted\">sshd -T<\/span> line should print &#8220;passwordauthentication no&#8221;, meaning SSH still refuses that password. Log in through the console once before you start the upgrade.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Run do-release-upgrade for Ubuntu 26.04 over SSH<\/h2>\n\n\n\n<aside class=\"hostry-author-note\" style=\"margin:26px 0;padding:16px 20px 14px;background:#fbf7ef;border-left:3px solid #eea416;border-radius:0 10px 10px 0;font-size:15px;line-height:1.6;color:#2b2f3a\"><div style=\"font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#b07a06;margin:0 0 6px\">From the engineer<\/div><p style=\"margin:0 0 12px\">Start the upgrade only when you can stay with it to the end, not at the close of a working day. Check the VNC console login before you begin, not after SSH has dropped.<\/p><div style=\"display:flex;align-items:center;gap:10px;font-size:13px;color:#5b6170\"><span style=\"display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;background:#11235e;color:#fff;font-size:12px;font-weight:700;flex:none\">SY<\/span><span><strong style=\"color:#11235e\">Stas Yantselovskiy<\/strong> \u00b7 System administrator &amp; DevOps engineer, Hostry<\/span><\/div><\/aside>\n\n\n\n<pre class=\"wp-block-code\"><code>grep ^Prompt \/etc\/update-manager\/release-upgrades\ndo-release-upgrade -c\nsudo do-release-upgrade<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line should read <span class=\"highlighted\">Prompt=lts<\/span>, the 24.04 default, and <span class=\"highlighted\">-c<\/span> only reports whether a release is available. The upgrade itself, as described in the <strong><a href=\"https:\/\/ubuntu.com\/server\/docs\/how-to\/software\/upgrade-your-release\/\" target=\"_blank\" rel=\"noopener\">Ubuntu Server guide to release upgrades<\/a><\/strong>, is interactive, and its prompts come in this order:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>&#8220;Continue running under SSH?&#8221; Answer yes. The next screen confirms the additional sshd on port 1022.<\/li><li>&#8220;Foreign Packages Installed&#8221; lists packages from outside the Ubuntu archive, such as docker-ce. Continue only if their vendors have 26.04 repositories.<\/li><li>A summary of packages to install, upgrade and remove. No package has been touched until you accept it.<\/li><li>Configuration file prompts: Y or I takes the maintainer&#8217;s version, N or O keeps yours (the default), D shows the diff. Press D; keep your file when the diff shows only your edits, otherwise take the new one and reapply them.<\/li><li>&#8220;Remove obsolete packages?&#8221; Read the list first. PostgreSQL server packages are on the upgrader&#8217;s never-remove list, so the old cluster survives.<\/li><li>The restart prompt. Ubuntu does not treat the system as upgraded until it has rebooted.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Screen keeps a log in <span class=\"highlighted\">\/var\/log\/dist-upgrade\/screenlog.0<\/span>, next to <span class=\"highlighted\">main.log<\/span> and <span class=\"highlighted\">apt.log<\/span>; read those first if anything fails.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When do-release-upgrade is not offering the new release<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong><a href=\"https:\/\/discourse.ubuntu.com\/t\/upgrades-from-ubuntu-24-04-lts-to-ubuntu-26-04-1-lts-now-enabled\/88502\" target=\"_blank\" rel=\"noopener\">Ubuntu announcement that 24.04 to 26.04.1 upgrades are enabled<\/a><\/strong> rolls out the Update Manager offer progressively, while Ubuntu Server users can start the upgrade at any time. When nothing is found, read the message. With <span class=\"highlighted\">Prompt=lts<\/span> the 24.04 tool says &#8220;There is no development version of an LTS available.&#8221; whenever it sees no newer LTS. <span class=\"highlighted\">Prompt=normal<\/span> gives &#8220;No new release found.&#8221;, and <span class=\"highlighted\">Prompt=never<\/span> blocks upgrades outright.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Check the Prompt line and that the server reaches changelogs.ubuntu.com over HTTPS, where the release list lives, then run <span class=\"highlighted\">do-release-upgrade -c<\/span> again. Leave <span class=\"highlighted\">-d<\/span> alone: it targets the development release, which the server guide does not recommend for production, and for LTS upgrades it only mattered before the first point release, which is out.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Post-flight checks after the reboot<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>1. Release and kernel<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>grep -E \"^(VERSION|VERSION_CODENAME)=\" \/etc\/os-release\nuname -r<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expect 26.04 (resolute) and a 7.0 kernel. The upgrade does not patch kernel CVEs: on November 2, 2026 the <strong><a href=\"https:\/\/ubuntu.com\/security\/CVE-2026-98432\" target=\"_blank\" rel=\"noopener\">Ubuntu tracker for CVE-2026-98432<\/a><\/strong> showed both releases&#8217; generic kernel as vulnerable, work in progress, so reboot into each kernel fix as it lands.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>2. Failed units and boot errors<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl --failed\njournalctl -b -p err --no-pager | tail -n 40<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;0 loaded units listed&#8221; is the pass. Match anything else against the service table earlier in the article before you touch configs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>3. sudo and SSH<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo --version | head -n 1\nsudo -l\nsudo sshd -t &amp;&amp; echo \"sshd config OK\"\nsudo grep -rl ssh-dss \/root\/.ssh \/home\/*\/.ssh 2&gt;\/dev\/null<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line should start with <span class=\"highlighted\">sudo-rs<\/span>. Log in from a new terminal before closing the old one, then remove the port 1022 rule with <span class=\"highlighted\">sudo ufw delete<\/span> plus its number, and the matching control panel rule.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>4. Third-party repositories<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>grep -l \"Enabled: no\" \/etc\/apt\/sources.list.d\/*.sources\nsudo apt update<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For each vendor you still need, change <span class=\"highlighted\">Suites: noble<\/span> to <span class=\"highlighted\">resolute<\/span> once the vendor supports it, delete the <span class=\"highlighted\">Enabled: no<\/span> line and confirm <span class=\"highlighted\">apt update<\/span> reads it without errors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:14px\"><strong>5. Containers, databases, runtimes<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker info 2&gt;\/dev\/null | grep -i cgroup\npg_lsclusters\nphp -v | head -n 1\npython3 --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Docker should report <span class=\"highlighted\">Cgroup Version: 2<\/span>. Then load the site, send a test email and run one scheduled job by hand.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recover a failed upgrade or a lost SSH connection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A dropped connection does not stop the upgrade, which keeps running inside screen. Reconnect on either port and look for the upgrader&#8217;s session. If it is listed, reattach to it; do not start <span class=\"highlighted\">do-release-upgrade<\/span> a second time.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh deploy@203.0.113.10 || ssh -p 1022 deploy@203.0.113.10\nsudo screen -ls\nsudo screen -d -r ubuntu-release-upgrade-screen-window<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If <span class=\"highlighted\">screen -ls<\/span> lists no such session, the upgrader process died. Do not reboot yet. Finish the half-configured packages and check which release APT points at:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dpkg --configure -a\nsudo apt -f install\ngrep ^Suites \/etc\/apt\/sources.list.d\/ubuntu.sources<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When the Suites line already says resolute, the switch happened: run <span class=\"highlighted\">sudo apt update &amp;&amp; sudo apt full-upgrade<\/span> to complete the move to 26.04. Once package installation has begun, the upgrader deliberately leaves the new sources in place; a comment in its code notes that the system is already part of the way through.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Noble usually means no 26.04 package was installed: an earlier abort copies your sources back from the <span class=\"highlighted\">.distUpgrade<\/span> backups. Confirm 24.04 in <span class=\"highlighted\">\/etc\/os-release<\/span>, find the reason at the end of <span class=\"highlighted\">main.log<\/span>, fix it and start again from the pre-flight list.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When the repair commands keep failing, read <span class=\"highlighted\">main.log<\/span> (what the upgrader decided), <span class=\"highlighted\">apt.log<\/span> (dependency problems) and <span class=\"highlighted\">screenlog.0<\/span> (the dpkg errors shown on screen) in <span class=\"highlighted\">\/var\/log\/dist-upgrade\/<\/span>. If the same package still fails after you fix the config file it names, stop forcing dpkg and rebuild from the backup. Reboot only once the commands finish cleanly and <span class=\"highlighted\">sudo sshd -t<\/span> passes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With SSH gone on both ports, open the VNC console in the Hostry control panel, log in with the password from step 8 and run the same repair commands. If it will not boot to a login, rebuild on a new VPS from the step 1 backup: reinstall packages with <span class=\"highlighted\">xargs -a manual-packages.txt sudo apt install<\/span> after deleting names 26.04 no longer ships, and before data goes on, work through <strong><a href=\"https:\/\/hostry.com\/blog\/secure-new-linux-vps-first-30-minutes\/\">SSH keys, UFW and automatic updates for a fresh Ubuntu server<\/a><\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Does a 22.04 server need two upgrades to reach 26.04?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. The 26.04 release notes say you must first reach 24.04 LTS or 25.10, so a 22.04 server goes through two release upgrades and two rounds of config prompts. A rebuild on 26.04 is often less work.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I have to switch from systemd-timesyncd to Chrony?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Chrony is the default only on new 26.04 installs, and an upgraded server keeps systemd-timesyncd. To move, the release notes give <span class=\"highlighted\">sudo apt-mark auto systemd-timesyncd<\/span> followed by <span class=\"highlighted\">sudo apt install chrony<\/span>. If you had edited <span class=\"highlighted\">\/etc\/chrony\/chrony.conf<\/span>, make sure its servers are not listed again in <span class=\"highlighted\">\/etc\/chrony\/sources.d\/ubuntu-ntp-pools.sources<\/span>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Whichever way the decision table points, rehearse before you upgrade Ubuntu 24.04 to 26.04 on production: order <strong><a href=\"https:\/\/hostry.com\/products\/vps\/\">a spare Hostry KVM VPS<\/a><\/strong>, restore your off-server backup onto it and run the same upgrade there. If it passes, repeat it on the live server, or keep the rebuilt server and move DNS to it. <strong><a href=\"https:\/\/hostry.com\/services\/vps\/\">Hostry VPS plans by location<\/a><\/strong> started at $6 a month when we checked, billed monthly.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Upgrades from Ubuntu 24.04 LTS to 26.04.1 LTS opened on September 29, 2026. Decide between an in-place upgrade and a rebuild, clear the blockers do-re&#8230;<\/p>\n","protected":false},"author":8,"featured_media":2927,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,15],"tags":[],"class_list":["post-2934","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-virtual-private-server","category-linux-server"],"read_time":10,"_links":{"self":[{"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/posts\/2934","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/comments?post=2934"}],"version-history":[{"count":3,"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/posts\/2934\/revisions"}],"predecessor-version":[{"id":2941,"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/posts\/2934\/revisions\/2941"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/media\/2927"}],"wp:attachment":[{"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/media?parent=2934"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/categories?post=2934"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hostry.com\/blog\/wp-json\/wp\/v2\/tags?post=2934"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}