
Automatic Linux Kernel Upgrades: Setup Guide
Automatic Linux kernel upgrades are worth setting up, but only after you can see what the automation does, confirm it ran, and boot back to a known-good kernel when it doesn't. Enable unattended-upgrades or a live-patching service blind and you trade a planned maintenance window for an unplanned outage at 3 a.m. The tooling is solid. The failure is almost always that nobody checked the kernel's role in the stack before turning the automation loose.
Last updated: 2026-07-21
The plan is simple. Understand the upgrade path first, keep manual updating as your baseline, then let automation handle the routine while you keep the rollback path armed.
What actually happens when the kernel upgrades?
A kernel upgrade is not one action, it's four, and automation orchestrates all of them. First the package manager downloads a new kernel package and installs it beside the old one. Your running kernel stays put. Nothing has switched yet.
Next the system rebuilds the initramfs, the small early-boot filesystem that loads the drivers needed to mount your real root. Then the bootloader gets updated so GRUB knows a new kernel exists and which one to boot by default. Only a reboot swaps the running kernel for the new one.
That last step is why kernel updates differ from every other package. apt upgrade on a library takes effect on the next process start. A kernel takes effect on the next boot, and not before. Run uname -r after an upgrade and you'll still see the old version until you reboot. That gap is where automation trips people up: the install succeeded, and the machine is still running the vulnerable kernel.
Update it by hand before you automate
Do it by hand once before you automate anything, so you know what a clean run looks like. On Debian or Ubuntu, run sudo apt update then sudo apt full-upgrade. Watch the output for the new linux-image package and the initramfs rebuild lines. On RHEL or Fedora, sudo dnf upgrade pulls the new kernel; on openSUSE, sudo zypper up does the same job.
Now verify each stage instead of trusting the "done" message. After the reboot, uname -r should print the new version. Run dmesg | grep -i error to check nothing failed to load during early boot. Confirm your out-of-tree modules came back with lsmod and, for anything DKMS-built, dkms status.
Compiling from source is a different animal and rarely what you want. Distribution kernels ship with security backports and tested configs. Build your own only when you need a feature or patch the packaged kernel doesn't carry, and expect to own every rebuild after that. For the full walkthrough, see our step-by-step guide to updating the Linux kernel.
When a new kernel is actually worth installing
Upgrade when there's a reason, not on a calendar reflex. The clear triggers are these:
- An actively exploited security flaw. A kernel CVE with a working exploit in the wild is a patch-now event, automation or not.
- Hardware or driver support. A new NIC, GPU, or storage controller that the running kernel doesn't recognize. This is the usual reason to move to Ubuntu's hardware enablement (HWE) kernel.
- End of life. A kernel past its support window stops getting fixes. Stay on it and you accumulate known holes.
- A real performance or stability regression you've traced to the kernel and confirmed is fixed upstream.
Absent one of those, a kernel that's been stable under your workload for months is an asset, not a liability. Newer is not automatically safer. Newer kernels often carry hardening and mitigations, but they also carry new bugs that haven't met your hardware yet.
Release cadence sets your options. The Linux mainline ships a new version every nine to ten weeks, which is too fast for most production. Long-term support (LTS) kernels are the sane default, though the LTS support window was trimmed from six years down to two, so pin your planning to the actual end-of-life date, not folklore. On RHEL and CentOS the vendor backports fixes into a stable base kernel across a ten-year lifecycle, so the version string barely moves while the security content keeps changing underneath it.
How does automated kernel updating work on Linux?
Three mechanisms cover almost everyone. On Debian and Ubuntu it's unattended-upgrades. On RHEL and Fedora it's dnf-automatic. Underneath both sit systemd timers that fire the job on a schedule, replacing the old cron approach.
Here is what each one does: it downloads and installs the new kernel package on your schedule. That's the part people miss. By default it does not reboot, so the new kernel sits installed and inactive while you keep running the old one. You have to opt into the reboot separately, and you have to mean it.
Confirm the job ran by reading its log, not by assuming. For unattended-upgrades, check /var/log/unattended-upgrades/unattended-upgrades.log and journalctl -u unattended-upgrades. For the dnf side, journalctl -u dnf-automatic.timer shows when it last fired. If the log shows a kernel installed but uname -r still shows the old version, that's expected until reboot, and it's the single most common "did it work?" question.
| Distribution | Tool | Key config file | Best use |
|---|---|---|---|
| Debian / Ubuntu | unattended-upgrades | /etc/apt/apt.conf.d/50unattended-upgrades | Automated security kernel patches |
| RHEL / CentOS | dnf-automatic (yum-cron on older releases) | /etc/dnf/automatic.conf | Predictable package apply cadence |
| Fedora | dnf-automatic | /etc/dnf/automatic.conf | Scheduled download and apply timers |
Configuring unattended upgrades without losing control

On Debian and Ubuntu, install the tool with sudo apt install unattended-upgrades, then edit /etc/apt/apt.conf.d/50unattended-upgrades to include the security origin and allow automatic kernel patches. The knob that matters most is Unattended-Upgrade::Allowed-Origins. Keep it scoped to the security pocket so the automation pulls security fixes and nothing more adventurous.
Reboots are where you decide how much control to give up. Two settings govern it:
Unattended-Upgrade::Automatic-Reboot "true";lets the machine reboot itself when an update needs it. Leave thisfalseon anything you'd hate to lose mid-session.Unattended-Upgrade::Automatic-Reboot-Time "03:00";pins that reboot to a quiet hour instead of the middle of the workday.
Turn on logging and then actually audit it. After a run, read /var/log/unattended-upgrades/unattended-upgrades.log to see what package was applied and whether a reboot was requested. That file is your evidence for compliance and your first stop when someone asks why a box bounced overnight. If you can't answer that from the log, your automation is running blind and so are you.
Where live patching helps and where it doesn't
Live patching swaps buggy kernel functions in memory without a reboot. Tools like kpatch, Canonical's Livepatch, Oracle Ksplice, and KernelCare load a small module that redirects a vulnerable function to a fixed version while the system keeps running. For a fleet where every reboot means draining traffic and losing an SLA minute, that's real value.
The catch nobody markets: not every fix is live-patchable. Changes to data structures, or fixes that touch how the kernel lays out memory, can't be hot-swapped safely. Those still need a real reboot into a new kernel. Live patching stretches the interval between reboots; it does not abolish them.
Treat it as a stopgap you'll eventually retire. Apply live patches to close a window fast, then still schedule a periodic full reboot onto the properly updated kernel. If you want the mechanics, we cover them in upgrading the kernel without a reboot. The teams that get burned ran live-patched for a year, never rebooted, and found their initramfs had been broken for months when the box finally cycled.
Automating kernel patches across a fleet

At fleet scale, unattended-upgrades on each host stops being enough. You want central orchestration: Ansible, Puppet, Red Hat Satellite, or AWS Systems Manager Patch Manager. The tool matters less than the pattern.
The pattern is staging. Patches flow through dev, then staging, then production, with a verification gate at each tier that has to pass before the next tier gets touched. An Ansible playbook is the common shape: update packages, detect whether a new kernel landed, reboot only if it did, then run a health check and fail the play loudly if the node doesn't come back clean.
- name: Upgrade kernel and reboot if needed
hosts: production
serial: 1
tasks:
- name: Apply security updates
apt: { upgrade: dist, update_cache: yes }
- name: Reboot if a new kernel was installed
reboot:
when: reboot_required.stat.exists
Run it serial: 1 or in small canary batches so one bad kernel takes down one node instead of the whole tier. Centralize the logs and alert on any failed install or unexpected reboot. The goal is that a broken upgrade pages a human before users notice, not after.
How do you verify a kernel upgrade succeeded?
Never treat "installed" as "deployed." Verify after the reboot with a handful of commands that each tell you something specific.
uname -r– the running kernel version. If it doesn't match what you installed, you didn't reboot, or GRUB booted the old entry.journalctl -b -p err– errors from the current boot only. A clean boot is a short list.dmesg | grep -i error– early kernel messages, where driver and hardware failures surface first.lsmodanddkms status– confirms your out-of-tree modules loaded. A DKMS module that failed to build shows here.
Learn the failure signatures. A kernel that boots but can't mount a filesystem points at initramfs or fstab, not the kernel binary. A NIC that never comes up points at a driver module that didn't rebuild against the new kernel. Silent success looks like a boring journalctl and a matching uname -r. That boredom is the whole point of verifying.
Rolling back a bad kernel
Reboot and pick the old kernel from the GRUB menu. Every distribution keeps at least the previous kernel installed by default, listed under "Advanced options" in GRUB. Boot it once to confirm the machine is healthy on the known-good version. That single test tells you whether you're fighting a kernel regression or something else.
To make the choice stick across reboots, set the default permanently. On RHEL and Fedora, sudo grubby --set-default /boot/vmlinuz-<good-version> pins it. On Debian and Ubuntu, edit GRUB_DEFAULT in /etc/default/grub and run sudo update-grub.
Then hold the version so automation doesn't reinstall the bad one tomorrow. On apt, sudo apt-mark hold linux-image-generic. On dnf, add exclude=kernel* in /etc/dnf/dnf.conf while you investigate. File the bug, wait for the fixed release, then unpin and retest. We walk the full recovery in rolling back a Linux kernel update. Arm this before you enable automation, not after it bites.
Where automatic upgrades bite
The reboot at the wrong moment is the classic. Automatic-Reboot "true" with no time window bounced a production box during business hours. Set the reboot time, or leave the reboot to a human on anything that matters.
The rest cluster around modules and boot files:
- Out-of-tree module breakage. Proprietary GPU drivers and anything DKMS-built have to recompile against each new kernel. When that fails, the module is gone after reboot and
dkms statusshows the failure. Check it as part of your post-upgrade verification. - Initramfs generation errors. A disk that filled up or a hook that errored can leave a truncated initramfs, and the machine won't boot. Rebuild with
sudo update-initramfs -uorsudo dracut -f. - A full
/boot. Every kept kernel eats space in/boot, and a small partition fills fast. Once it's full the initramfs rebuild fails silently. Prune old kernels; our guide on removing unused kernel modules covers the cleanup. - Mismatched firmware. A new kernel that expects newer firmware blobs can leave a device half-working.
dmesg | grep -i firmwareshows the request that failed.
None of these are exotic. They're why the rule stands: automate the install, keep verification and rollback in the loop, and read the log before you trust the machine.
The kernel is documented in depth at the official kernel documentation, and it's worth knowing where the security fixes you're automating actually come from. If your interest is hardening rather than just patching cadence, see preventing kernel exploits in Linux.
FAQ
Does installing a new kernel automatically activate it?
No. The install puts the new kernel on disk next to the old one and updates GRUB, but the running kernel doesn't change until you reboot. This is why uname -r can show an old version right after a successful upgrade. Any automation that installs kernels but never reboots leaves you running the old, still-vulnerable one.
Can I run automatic upgrades and still control reboots?
Yes, and you usually should. Configure the tool to download and install on a schedule but leave Automatic-Reboot set to false, then reboot the machine yourself during a planned window. You get timely patching without a surprise bounce. Pair it with a live-patching service if you need the fix active before the next scheduled reboot.
How often should I run automatic kernel checks?
A daily check for security updates is a reasonable default for most servers. The check is cheap because it only downloads and installs; the disruptive part, the reboot, stays on your own cadence. Weekly or monthly is fine for low-risk machines, but stretch the interval and you widen the window an active exploit can use.
Is cron still fine for scheduling kernel updates?
It works, but systemd timers are the better fit on any modern distribution. Timers give you logging through journalctl, dependency handling, and randomized start delays so a whole fleet doesn't update in the same second. Keep cron for a quick one-off; use timers, or the built-in tool's own scheduler, for anything you rely on.
Should I ever disable automatic kernel upgrades entirely?
On tightly change-controlled systems, yes. Machines with certified kernels, real-time patches, or vendor-locked module stacks should hold their kernel and update only through a reviewed change ticket. For those, pin the version with apt-mark hold or a dnf exclude, and treat every kernel move as a deliberate, tested event rather than a background job.
