Ubuntu 26.10 Upgrade Checklist for Servers
Ubuntu 26.10 ships Rust coreutils, drops SysV init scripts, moves to OpenSSL 4 and splits OpenSSH. Here is what breaks and a script to audit your servers first.
BY ASHLIN DARIUS GOVINDASAMY
Ubuntu 26.10 "Stonking Stingray" is scheduled for release on 15 October 2026, and its release notes read like a list of things your servers quietly depend on. If you are planning an Ubuntu 26.10 upgrade, the headline items are coreutils rewritten in Rust, the removal of the SysV init script bridge, OpenSSL 4, and an OpenSSH package split.
None of this is scary if you find it before the upgrade rather than after. This post walks through the breaking changes the official release notes call out, then gives you an audit script to run on each box. 26.10 is an interim release, so you are the early-adopter kind of person here. Pick your battles accordingly.
What actually changed in Ubuntu 26.10
The release images use Linux kernel 7.3, built from 7.3-rc6 because the final upstream release lands after general availability. Toolchains are current: GCC 15.2.0, LLVM 22.1.8, Python 3.14.7, Rust 1.97.1 and Go 1.27. The parts that can bite an existing server are these:
- Core utilities now run entirely on the Rust-based uutils implementation, including cp, mv and rm, which had stayed on GNU for compatibility reasons.
- The systemd component systemd-sysv-generator, which turned /etc/init.d scripts into services at runtime, has been removed.
- OpenSSL 4 ships, and OpenSSL ENGINE support is gone, so configs referencing the pkcs11 engine must move to the provider.
- OpenSSH is split into openssh and openssh-gssapi source packages. Fresh installs get the non-GSSAPI build.
- HAProxy 3.4.2 changes the default load-balancing algorithm from roundrobin to random (power of two choices).
Rust coreutils: cp, mv and rm are now uutils
The release notes say plainly that the default core utilities now run entirely on uutils. Ubuntu already moved most tools in an earlier release, so 26.10 finishes the job by migrating the three commands that were held back.
For interactive use you will not notice. For scripts that parse output, rely on obscure flags, or run unattended as root, you want proof rather than faith. The cheapest test is to diff behaviour between the two implementations on a scratch directory.
ls --version | head -1
cp --version | head -1
tmp=$(mktemp -d) && cd "$tmp"
mkdir -p src/sub && echo hello > src/sub/a.txt && ln -s a.txt src/sub/link
# Flags that scripts love
cp -a src dst
cp --reflink=auto src/sub/a.txt copy.txt
mv -n copy.txt copy2.txt
rm -rf --one-file-system dst
diff -r src src && echo "tree intact"SysV init scripts no longer become services
This is the one that can take a service offline silently. systemd used to scan /etc/init.d at boot and synthesise a unit for any script without a native one. That generator is removed. Packages that depended on it either ship a real systemd unit now or were dropped if unmaintained, but your own scripts, or third-party vendor installers, get no such rescue.
The audit is simple: list every executable in /etc/init.d that has no matching systemd unit.
for f in /etc/init.d/*; do
name=$(basename "$f")
[ "$name" = "README" ] && continue
[ "$name" = "skeleton" ] && continue
if ! systemctl list-unit-files "$name.service" --no-legend 2>/dev/null | grep -q .; then
echo "NO UNIT: $name"
fi
doneAnything printed needs a unit file. A minimal one is usually five lines, and it is better than the script ever was because systemd handles restarts, logging and dependencies for you.
[Unit]
Description=Legacy app, formerly /etc/init.d/legacy-app
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/opt/legacy-app/bin/legacy-app --foreground
Restart=on-failure
User=legacy
[Install]
WantedBy=multi-user.targetQUICK CHECK
A vendor installer dropped /etc/init.d/agent and nothing else. What happens on 26.10?
OpenSSL 4 and the death of ENGINE
OpenSSL 4 brings Encrypted Client Hello and expanded QUIC support, per Ubuntu's notes. It also no longer supports engines. The libengine-pkcs11-openssl package now ships only the PKCS#11 provider. If you use hardware tokens or HSMs through the pkcs11 engine, any configuration that names that engine will stop working until it points at the provider instead.
grep -rIn --include="*.cnf" --include="*.conf" -iE "engine|pkcs11" /etc 2>/dev/null
openssl version
openssl list -providersAlso grep your own code and build scripts for ENGINE_ API calls and the -engine command-line flag. Those are the same dependency in a different costume.
OpenSSH split and the HAProxy default
OpenSSH now comes from two source packages. The openssh binaries exclude GSSAPI and Kerberos support. The openssh-gssapi source builds the GSSAPI-enabled openssh-gssapi-server and openssh-gssapi-client. The variants conflict, so installing one removes the other. Fresh installs default to non-GSSAPI, and the release notes warn the upgrader may pick the GSSAPI packages. If you use Kerberos single sign-on over SSH, verify which flavour you end up with.
sshd -T | grep -i gssapi
grep -rIn -i gssapi /etc/ssh ~/.ssh/config 2>/dev/null
dpkg -l | grep -E "openssh-(server|client|gssapi)"HAProxy 3.4.2 changes the default balance algorithm from roundrobin to random with power-of-two-choices, where it picks two servers at random and sends the request to the less loaded one. That is a sensible default for fleets, but if your backend relied on implicit round-robin ordering, or you never set balance at all, behaviour will shift. The fix is to be explicit.
backend app
balance roundrobin
# or: balance random(2)
server a 10.0.0.11:8080 check
server b 10.0.0.12:8080 check›Why power of two choices is a good default
Pure random balancing can pile requests onto one server by bad luck. Round robin ignores how busy each server actually is. Sampling two servers at random and choosing the one with fewer in-flight requests gets close to the evenness of full least-connections tracking while staying cheap and friendly to multiple load balancers, which is why it makes sense as a default for modern fleets.
A one-shot preflight script
Put the checks together and run them on a staging clone before touching production. Nothing here modifies the system.
#!/usr/bin/env bash
set -u
echo "== init.d scripts without a unit"
for f in /etc/init.d/*; do
n=$(basename "$f"); [ "$n" = README ] && continue; [ "$n" = skeleton ] && continue
systemctl list-unit-files "$n.service" --no-legend 2>/dev/null | grep -q . || echo " $n"
done
echo "== engine/pkcs11 config"
grep -rIl -iE "engine|pkcs11" /etc --include="*.cnf" --include="*.conf" 2>/dev/null | sed 's/^/ /'
echo "== gssapi in use"
sshd -T 2>/dev/null | grep -i '^gssapi' | sed 's/^/ /'
echo "== haproxy balance not set"
grep -rLn "balance" /etc/haproxy 2>/dev/null | sed 's/^/ /'
echo "== done"A sane rollout order
Resist the urge to upgrade everything at once. Start with a disposable machine: snapshot a staging server, run the preflight script, then run do-release-upgrade and see what the real upgrader does. Pay particular attention to the OpenSSH prompt, because the release notes warn that the upgrader may select the GSSAPI packages, and you want to know that before it happens on a box you can only reach over SSH.
Next, exercise your automation rather than your intuition. Backup jobs, log rotation, deploy scripts and cron entries are exactly where cp, mv and rm are called with unusual flags, and they run when nobody is watching. Run each of them once by hand on the staging copy and compare the result with production. Treat any difference in exit codes, error text or file metadata as a bug to investigate, not noise to ignore.
Finally, put the changes in version control. The unit files you write to replace init scripts, the explicit balance line in HAProxy and any provider-based OpenSSL configuration belong in your configuration management, so the next machine you build already has them. That turns a one-off migration into a permanent improvement, and it means the upgrade checklist shrinks every time you use it.
- Snapshot or clone a staging server and run the preflight script.
- Run do-release-upgrade there and note every package prompt, especially OpenSSH.
- Run backups, deploys and cron jobs once by hand and diff the results.
- Replace init scripts with unit files and commit them to config management.
- Make HAProxy balance explicit, then upgrade production one node at a time.
The takeaway
Ubuntu 26.10 is mostly a memory-safety and modernisation release, and the cost is a handful of assumptions that no longer hold: init scripts, OpenSSL engines, implicit load-balancing and GSSAPI-enabled SSH. Run the preflight, write the five-line unit files, make your HAProxy config explicit, and the upgrade becomes boring, which is exactly what an upgrade should be.
SOURCES
- Ubuntu 26.10 release notes — Canonical
- OpenSSL 4.0.0 release — OpenSSL / GitHub
- Announcing HAProxy 3.4 — HAProxy Technologies
Frequently asked questions
When is Ubuntu 26.10 released?
It is scheduled for 15 October 2026. It is an interim release, so it is supported for a shorter period than an LTS.
Does Ubuntu 26.10 use Rust coreutils?
Yes. The release notes say the default core utilities now run entirely on the Rust-based uutils implementation, including cp, mv and rm.
What replaces systemd-sysv-generator in Ubuntu 26.10?
Nothing replaces it. The component that created services from /etc/init.d scripts has been removed, so each service needs a native systemd unit file.
Why did my PKCS#11 configuration stop working with OpenSSL 4?
OpenSSL 4 removed ENGINE support. Configurations that reference the pkcs11 engine must be migrated to the PKCS#11 provider shipped in libengine-pkcs11-openssl.
NEWSLETTER
Get the engineering notes in your inbox.
Kernels, GPUs, networks, AI infrastructure — and the things we broke along the way. No spam, one click to leave.
We store only your email address, to send you new articles. See our privacy policy.
TAGS
RELATED
Building a Reverse Proxy From Scratch
What nginx and Envoy are actually doing under their config files — routing, connection handling and failure modes, implemented directly.
Fixing Linux Freezes During Steam Downloads
Steam hits full speed and the whole Linux desktop locks up. A root-cause walkthrough of dirty page writeback, dm-crypt workqueues and QLC SSD cache exhaustion — and the exact sysctl and cryptsetup fixes.