Tomorrow, July 9, 2026, Ubuntu 25.10 “Questing Quokka” stops getting security patches. If you’ve got a server, a CI runner, or a dev box still on it, this is the last day it’s a supported operating system. After that, every CVE that lands in the kernel, in OpenSSL, in glibc — nothing gets backported. You’re running on borrowed time with no landlord answering the phone.
Interim releases like 25.10 only get nine months of support, which always feels like plenty of runway right up until it isn’t. The good news is the upgrade target has been out for a while: Ubuntu 26.04 LTS “Resolute Raccoon” shipped back in April, so this isn’t a same-day scramble onto a brand-new release with day-one bugs. It’s had three months to shake out. Here’s how to actually do the upgrade without taking down anything that matters.
Why this deadline is different from a desktop nag screen
If you’ve only run Ubuntu on a laptop, EOL probably means a yellow notification you click away. On a server it means something sharper: apt starts failing because the package repos for 25.10 go away, unattended-upgrades has nothing left to fetch, and any security scanner your org runs (Trivy, Grype, whatever compliance mandates) starts flagging a pile of unpatched CVEs with no fix version available — because there won’t be one. If you’re under SOC 2 or ISO 27001, an EOL OS is exactly the kind of finding an auditor loves to write up.
The fix isn’t complicated, but it’s also not “click upgrade and walk away” on anything you actually depend on. Treat it like you’d treat any major-version bump: back up, test, upgrade, verify.
Before you touch do-release-upgrade
A few minutes of prep here saves you from the two most common ways this goes sideways.
Snapshot first. If you’re on AWS, GCP, or Azure, take an AMI/image snapshot or a disk snapshot before you start. This is the one step people skip because “it’s just an OS upgrade” and then regret for the rest of the afternoon. A snapshot turns a bad upgrade into a five-minute rollback instead of a rebuild-from-scratch afternoon.
Fully update 25.10 first. Run sudo apt update && sudo apt full-upgrade -y and reboot if a new kernel came down. Most upgrade failures trace back to one of three things: the system wasn’t fully patched before the jump, a kernel update never got a reboot to actually apply, or a third-party PPA breaks dependency resolution mid-upgrade. Fix the first two before you start; they’re free.
Disable third-party PPAs. This is the one that bites people running Docker hosts or anything with a non-default kernel or userspace tool installed via PPA. do-release-upgrade will usually disable them automatically, but do it yourself first and re-enable one at a time afterward once you’ve confirmed each PPA has 26.04 packages. If you upgrade with a stale PPA still active, you’ll get an “unresolvable problem occurred” error partway through, at which point you’re debugging a half-upgraded system instead of a clean one.
Check for the two hard blockers. Systems still running the cgroup v1 hierarchy, and IBM Z hardware at the z14 generation or older, cannot upgrade to 26.04 LTS at all — the upgrade tool will refuse. If you’ve got an older container host that never migrated off cgroup v1 (some Kubernetes 1.24-era nodes never did), you need to fix that first and separately, then come back to the OS upgrade.
The upgrade path
For a server, the whole thing is one command, run inside screen or tmux so a dropped SSH session doesn’t kill the upgrade halfway through:
sudo apt update && sudo apt full-upgrade -y
sudo do-release-upgradeIt walks you through package removals, config file conflicts (it’ll ask about anything you’ve hand-edited, like /etc/ssh/sshd_config — read these prompts, don’t just mash “keep the local version” on autopilot), and a final reboot. On a typical small VM this takes 15-30 minutes depending on how many packages you’ve got installed and how far your mirror is.
If do-release-upgrade tells you no new release is available, it’s usually because you’re not on the latest 25.10 point release yet, or you’re using -d incorrectly for what should be a normal LTS jump — 26.04 is a regular release target for 25.10, not a devel-only one, so you shouldn’t need the -d flag at all here.
A couple of specific error messages worth knowing before you hit them cold. “Please install all available updates for your release before upgrading” means exactly what it says — go back and run apt full-upgrade again, there’s a stray package that didn’t get picked up the first time. “An unresolvable problem occurred” almost always traces back to a PPA that hasn’t published 26.04-compatible packages yet; the tool will usually tell you which repository it’s stuck on if you scroll up in the log at /var/log/dist-upgrade/main.log. Don’t try to force through a dependency conflict with apt --fix-broken mid-upgrade — back out, disable the offending PPA, and restart the upgrade cleanly instead.
What actually breaks
Docker. This is the one that catches people off guard because it’s not a version bump, it’s a default change. Fresh Docker installs on 26.04 now use the containerd image store by default instead of the classic overlay2 graphdriver. If you’re upgrading an existing host rather than installing fresh, your existing docker.io config is left alone — you keep your current storage driver. But docker image ls output format changes either way, to a collapsed tree-style view. If you’ve got scripts parsing docker image ls output (you shouldn’t, but people do), check them before you upgrade, not after something quietly stops matching.
Snap transitions. A handful of packages that were .deb on 25.10 continue their slow march to snap-only on 26.04. If you’ve got automation that assumes a .deb-installed binary at a specific path, verify it’s still there post-upgrade rather than discovering it’s now a snap in a container namespace during an incident.
systemd unit changes. Minor version bumps in systemd occasionally rename or restructure unit files for services you don’t manage directly (networking, journald). If you’ve got custom systemd overrides or drop-in files targeting a unit that got restructured, verify they still apply with systemctl status <unit> after the reboot — a silently-ignored override is worse than a loud error.
cloud-init and unattended-upgrades. Both get reconfigured during the upgrade to defaults for the new release. If you’d customized either — a specific unattended-upgrades schedule, or cloud-init user-data behavior for auto-scaling groups — diff your configs against the pre-upgrade backup and reapply anything that got reset.
If you’re running this on a CI runner, not just a server
Self-hosted GitHub Actions runners, GitLab runners, and Jenkins agents on Ubuntu 25.10 are the box most likely to get forgotten in an EOL sweep, because nobody logs into them interactively — they just sit there executing jobs until something breaks. A few things specific to runners:
Pin the runner offline before you upgrade it, not after. For GitHub Actions, that’s removing it from the pool (or letting it finish its current job and then stopping the service) so a job doesn’t land mid-upgrade and either hang or fail in a confusing way that looks like a pipeline bug instead of an infra one. Same idea for GitLab: gitlab-runner stop before you touch the OS.
Check what your build steps assume about the base image. A runner that’s been alive for a year or two accumulates assumptions nobody wrote down — a specific glibc version some binary was compiled against, a Python or Node version installed outside your build’s own toolchain management, a system package your Dockerfile’s builder stage expects to already exist on the host. The upgrade won’t remove any of that, but the versions of those things move, and a build that never pinned its toolchain versions explicitly can start failing for reasons that have nothing to do with your actual code changes. If your CI has been green for months, run one throwaway pipeline against the upgraded runner before you trust it back into the real pool.
If you run a fleet of runners rather than one, upgrade them one at a time and watch the first one for a day before touching the rest. This is the same logic as a canary deploy — an EOL upgrade across your whole CI fleet in one afternoon is exactly the kind of thing that turns a one-runner problem into “why did every PR in the company fail to build this morning.”
Rollback and verification
If the snapshot step above felt like overkill, this is where it pays for itself. If the upgrade fails in a way that leaves the box unbootable or broken in some way you don’t want to debug live, restore the snapshot and you’re back to a known-good 25.10 state in the time it takes the volume to reattach — then you can retry the upgrade with more prep, or in a maintenance window instead of live.
Once you’re up and it looks fine, don’t just eyeball the prompt and move on. Check:
lsb_release -a # confirms 26.04
uname -r # confirms new kernel
docker ps # containers actually restarted and healthy
systemctl --failed # any services that didn't come backsystemctl --failed in particular is worth running even if everything looks fine — it’s the fastest way to catch a service that silently didn’t restart after the reboot instead of finding out three days later when something depending on it breaks.
The bigger-picture reason to not put this off
26.04 is an LTS release, so once you’re on it you’re not doing this again for a while — standard support runs to April 2031, and if you’re on Ubuntu Pro (free for personal use, paid for commercial at scale), Expanded Security Maintenance stretches that to 2036, with a further Legacy add-on tier pushing total coverage past that if you really need to run something for fifteen years. Compare that to the nine months you just got from 25.10, and the case for jumping straight to an LTS rather than interim-hopping again is pretty obvious — assuming your workload doesn’t need bleeding-edge kernel or package versions that only interim releases carry.
If you’re managing more than a couple of boxes, this is also a good moment to check whether you actually need to be on interim releases at all going forward. Interim Ubuntu releases exist for people who want newer packages sooner and are willing to trade that for a nine-month support window and upgrades roughly three times a year. For most production servers, that trade isn’t worth it — LTS-only is one upgrade every two years instead of a EOL deadline showing up in your calendar every nine months.
Sources: 9to5Linux, UbuntuHandbook, Canonical, Ubuntu release cycle