Kernel updates: what to keep, what to check, what breaks
2026-02-11
What is installed is not what is running
uname -r # running now
dpkg -l 'linux-image-*' 'linux-headers-*' | grep '^ii'
apt-mark showmanual | grep '^linux-' # what is held explicitly
grub-editenv list 2>/dev/null # the saved default entry
Keeping two kernels is the sane policy: the newest, and the one before it. More than that
is how /boot fills, and a full /boot is discovered during the next
upgrade, halfway through it, with dpkg in a half-configured state.
df -h /boot
apt-get -s autoremove --purge | head # what would be removed; read it before doing it
apt-get autoremove --purge
Check this before an unattended upgrade window rather than after. The failure is not the kernel, it is the packaging transaction that could not write the initramfs.
The things that must be rebuilt
- DKMS modules — anything out of tree (a vendor driver, a VPN or
filtering module) has to compile against the new headers. If
linux-headers-*for the new version is not installed, the build is skipped silently and the module is simply absent after the reboot. linux-modules-extra-*— filesystem drivers and most hardware support live here, not in the base kernel package. A machine that boots and then cannot see a disk or a network card usually is missing this package for the new version.- Secure Boot — an unsigned module is refused at load time with
Key was rejected by service. Either keep the signing enrolled or expect to disable it; do not discover this on the one reboot that matters.
Verify after the reboot, before walking away:
uname -r
lsmod | wc -l
dmesg --level=err,warn | grep -Ei "module|firmware|failed to" | head
systemctl --failed
Deciding when to reboot
Knowing what is waiting for a reboot is the useful part:
needrestart -b # services still running old binaries/libraries
needs-restarting -r 2>/dev/null || true # the rpm-world equivalent, if you are on that
cat /proc/sys/kernel/tainted # non-zero: out-of-tree modules loaded
A kernel change waits for a reboot; a library change waits for a service restart, and those are different decisions. The second one is usually boring and can be done now; the first one is a downtime event and should be scheduled rather than discovered.
Changing what boots
grep -E "^menuentry|^submenu" /boot/grub/grub.cfg | cut -d"'" -f2 | head
sudo grub-reboot "1>2" # boot this entry once, then revert to the default
sudo reboot
A one-off entry selection is much safer than editing the default, and it is the right move when trying a new kernel on a machine you cannot physically reach: if it does not come back, the next boot is the old kernel by itself.
When the new kernel is the problem
Boot the previous one from the menu, then pin it so an automatic upgrade cannot move you forward again underneath you:
sudo apt-mark hold linux-image-generic linux-headers-generic
apt-mark showhold
A hold is a decision with an expiry date, and the date should be in a calendar rather than in a comment nobody opens — see apt holds and pins.