SSD Nodes Learn Hosting plans →
Guides Matt ConnorBy Matt Connor

Which updates need a reboot on Rocky/Alma

A dnf update leaves the old kernel and old libraries running on Rocky and Alma. Use needs-restarting to see what needs a reboot and what needs a restart.

Which updates need a reboot on Rocky Linux and AlmaLinux

On Rocky Linux and AlmaLinux, dnf update writes new files to disk and stops there. The kernel you booted keeps running. Every process that already opened a library keeps using the copy it opened, because Linux keeps the old file alive on disk until the last process holding it exits. So the machine can report zero available updates while it still runs the code those updates replaced.

Which updates need a reboot, and which need only a service restart, is a question you have to ask the machine. The command that answers it is needs-restarting. Updates sort into three tiers. The kernel and a short list of core packages need a full reboot. Ordinary library updates need the services that use them restarted. Everything else is already applied the moment RPM finishes.

Install needs-restarting

needs-restarting is a DNF plugin. The plugin ships in dnf-plugins-core, which is present on most Rocky and Alma installs already. The /usr/bin/needs-restarting command is a small wrapper shipped in dnf-utils.

sudo dnf install -y dnf-utils
needs-restarting --help

Both spellings run the same code, because the wrapper calls the DNF subcommand:

needs-restarting -r
dnf needs-restarting -r

Both packages come from the distribution's own repositories, so you do not need EPEL or the CRB repository enabled for this.

On the Rocky Linux 10 and AlmaLinux 10 line, dnf is DNF 5 and needs-restarting is one of its own commands, from the dnf5-plugins package. There, dnf needs-restarting with no options gives the reboot answer directly. -r is still accepted, and the manual says it has no effect and exists only so DNF 4 scripts keep working.

Tier 1: the updates that need a reboot

Run the reboot check first. It reads the RPM database and the system boot time, nothing else, so it is fast and it does not need root.

needs-restarting -r

When nothing important has changed since boot, it prints two lines:

No core libraries or services have been updated since boot-up.
Reboot should not be necessary.

When something has changed, it prints Core libraries or services have been updated since boot-up:, then the package names it found, and then:

Reboot is required to fully utilize these updates.
More information: https://access.redhat.com/solutions/27943

The exit code carries the same answer: 0 when no reboot is needed, 1 when one is. That is the half you script against.

if ! needs-restarting -r >/dev/null; then
  logger -t updates "reboot pending on $(hostname -s)"
fi

Exit code 1 here is a normal answer, not a failure. Under set -e an unguarded needs-restarting -r ends your script at that line, which is why the example above wraps it in if.

The packages that trigger the reboot answer are a short hard-coded list inside the plugin. In current versions it holds kernel, kernel-core, kernel-rt, glibc, linux-firmware, systemd, dbus, dbus-broker, dbus-daemon and microcode_ctl. Older plugin builds carry a slightly shorter list, so check yours rather than assuming.

Each entry is on that list for a reason you can state plainly. A new kernel package only writes files into /boot and /lib/modules, and the running kernel cannot be swapped underneath itself, so nothing changes until you boot it. Every process on the box links glibc, which means "restart the affected services" would mean restarting PID 1 as well, and a reboot is the safe version of that. dbus and dbus-broker carry every client connection on the system, so stopping the bus on a live machine breaks the clients that are talking to it. linux-firmware and microcode_ctl load at boot, and on a VPS the microcode part usually changes nothing you can observe, because the hypervisor host owns the physical CPU.

You can add your own packages. Any .conf file under /etc/dnf/plugins/needs-restarting.d/ is read as a list of package names, one per line, and those names join the reboot list.

echo 'openssl-libs' | sudo tee /etc/dnf/plugins/needs-restarting.d/openssl.conf

That is a policy choice, not a fix. It says "when the TLS library changes, I would rather reboot than track down every service that mapped it".

What the reboot hint is actually derived from

needs-restarting -r does not compare your running kernel version against the newest installed kernel. It compares timestamps. For every package on that core list it reads the RPM install time and compares it against the time the system booted. If a core package was installed after the last boot, the answer is "reboot required". Boot time comes from systemd's UnitsLoadStartTimestamp over D-Bus when that is available, and otherwise from the later of the modification time of /proc/1 and the btime field in /proc/stat.

That mechanism has one consequence worth knowing. If you install a kernel, reboot, and land back on an older kernel because the boot default is pinned, the install time is now older than the boot time and needs-restarting -r goes quiet. It is answering its own question correctly. It is not the question you asked. Check the kernel separately.

uname -r
rpm -q --last kernel
sudo grubby --default-kernel

The first command prints what is running. The first line of rpm -q --last kernel is the most recently installed kernel. grubby --default-kernel prints what the bootloader will pick next time. If those three disagree, fix the boot default before you reboot a machine you cannot reach over a console.

Tier 2: the updates that need a service restart

When RPM replaces a shared library, it unlinks the old file and writes a new one. A process that already mapped the old file keeps the old inode alive and keeps executing the old code. openssl-libs is the case that matters most: a fix in libcrypto reaches your web server only after that web server restarts.

sudo needs-restarting -s

This lists the systemd services whose own files, or whose dependencies' files, were updated after the service started. Use sudo. Without root the tool can only read /proc entries for your own processes, so it quietly under-reports and the short list looks like good news.

sudo needs-restarting
sudo needs-restarting --exclude-services

The first prints the PID and command line of every affected process. The second drops the ones a systemd service already covers, which leaves login shells, tmux sessions, cron jobs and anything you started by hand. Those never restart on their own.

If a service on the list is also a reboot-tier package, the tool prints Warning: The following services should not be restarted but require a reboot: above it. Take that literally and reboot instead.

Restart the rest one at a time, and check each one before moving to the next.

sudo systemctl restart nginx
systemctl status nginx

Do not pipe the list into systemctl restart. Your own SSH session is the reason. On the RHEL family, sshd.service ships with KillMode=process, so restarting it signals the listening daemon and leaves the per-connection processes alone, and an open session survives. Confirm that on your own box with systemctl cat sshd | grep KillMode, and keep a second session open the first time regardless.

You can also find the same processes without DNF, which is useful when you want to see the file paths involved:

sudo dnf install -y lsof
sudo lsof -n +c 0 2>/dev/null | grep -w DEL

DEL marks a mapped file that has been deleted from disk. Read the paths before acting. Deleted temporary files and memory-backed files show up here too, and they are not a reason to restart anything.

Tier 3: everything else

Most updates land here and need nothing. A package whose files are only read when a command starts, such as curl, tar, vim or dnf itself, is fully applied when RPM finishes, because the next run reads the new binary. Configuration files, scripts, documentation and data packages behave the same way. needs-restarting will not mention any of them, and that silence is the correct answer rather than a missed detection.

The one catch in this tier is duration. A process started before the update keeps running its old executable until it exits, however trivial the package was. That is exactly what sudo needs-restarting --exclude-services is for.

Why a machine on dnf-automatic can carry unapplied fixes for weeks

This is where the three tiers stop being trivia. Automatic updates with dnf-automatic install packages on a timer, and the default reboot setting in /etc/dnf/automatic.conf is never. With apply_updates = yes and reboot = never, a machine can install six kernel updates and a glibc fix over six weeks and still be running the kernel and the C library it booted with in week zero. The update log looks perfect. The running system has none of it.

The fix is three lines in /etc/dnf/automatic.conf:

[commands]
upgrade_type = security
apply_updates = yes
reboot = when-needed
reboot_command = "shutdown -r +5 'Rebooting after applying package updates'"

reboot accepts never, when-changed and when-needed. never is the default and leaves every decision to you. when-changed reboots after any transaction that changed a package, which is blunt but predictable. when-needed asks DNF whether the transaction it just applied requires a reboot, so a userspace-only update night passes without one. reboot_command is what actually runs, and the default gives logged-in users five minutes of warning. Set random_sleep and the timer's schedule so this lands inside a window where you can watch the machine come back.

Check which unit you enabled with systemctl list-timers 'dnf-*'. Several variants ship with dnf-automatic and they do not all behave the same way, so the config file alone does not tell you what runs.

After a scheduled run, ask the machine rather than the log:

needs-restarting -r; echo "exit: $?"
uname -r
rpm -q --last kernel | head -1

If the reboot is the part you cannot schedule, live kernel patching on a VPS is the other route. It applies certain kernel fixes to the running kernel with no reboot. It covers a subset of kernel issues, and it does nothing for glibc or for your services, so treat it as a way to space reboots out rather than to stop doing them. When you do reboot, do it deliberately and stay logged in until the machine answers, because a kernel update is the most common reason a machine does not come back. Read what to do when a VPS will not boot after a kernel update before you reboot a box with no console access, and fold the reboot check into a regular server maintenance checklist so it is not something you remember only after an incident.

The same job on Ubuntu and Debian

A mixed fleet needs the equivalents. On Ubuntu and Debian the reboot flag is a file, not a command: package scripts create /run/reboot-required, and /run/reboot-required.pkgs lists which packages asked for it, so [ -f /run/reboot-required ] is the plain equivalent of needs-restarting -r. Older documentation writes /var/run/reboot-required, which is the same file, because /var/run is a symlink to /run. The service side is needrestart, installed by default on recent Ubuntu Server releases, which runs during apt upgrade and can be run on its own with sudo needrestart -r l to list what needs restarting without touching anything. The automatic-update gap is identical there, and so is the fix: unattended-upgrades on Ubuntu takes Unattended-Upgrade::Automatic-Reboot "true"; and Unattended-Upgrade::Automatic-Reboot-Time "02:00"; in /etc/apt/apt.conf.d/50unattended-upgrades.

Failure modes and what you will see

  • needs-restarting: command not found means dnf-utils is not installed. Install it, or call dnf needs-restarting instead, which works as soon as dnf-plugins-core is present.
  • A script that stops at the reboot check with no error message is hitting exit code 1 under set -e. That code means "reboot required", so branch on it instead of letting it terminate the script.
  • needs-restarting -s printing nothing right after a library update usually means you ran it without sudo. Without root it sees only your own processes.
  • needs-restarting -r reporting no reboot while uname -r shows an old version means you booted an older kernel. The check compares install time against boot time, and both are now behind you. Look at grubby --default-kernel.
  • A service that appears again on the next run, minutes after you restarted it, is usually being restarted by something else, or the unit failed to come back. Read systemctl status for that unit before restarting it a second time.

FAQ

Does dnf update restart services on Rocky Linux?

As a rule, no. The transaction writes files and ends. Some packages do carry an RPM scriptlet that restarts their own service on upgrade, so behaviour is per package rather than a system-wide guarantee. Treat sudo needs-restarting -s as the authority: it lists the services whose files, or whose dependencies' files, changed after the service started, whatever the scriptlets did.

Why does needs-restarting -r say no reboot is needed when a newer kernel is installed?

Because it compares the RPM install time of a short list of core packages against the system boot time. It never compares the running kernel version against the newest installed one. If you installed a kernel, rebooted, and came back on an older kernel because the bootloader default points there, the install time is older than the boot time and the check goes quiet. Run uname -r, rpm -q --last kernel and sudo grubby --default-kernel to see the real picture.

Which packages trigger the reboot hint on Rocky and Alma?

A hard-coded list inside the plugin, which in current versions holds kernel, kernel-core, kernel-rt, glibc, linux-firmware, systemd, dbus, dbus-broker, dbus-daemon and microcode_ctl. You can extend it: drop a .conf file into /etc/dnf/plugins/needs-restarting.d/ containing package names, one per line, and those names count toward the reboot answer too.

Can dnf-automatic reboot the server by itself?

Yes. Set reboot = when-needed in the [commands] section of /etc/dnf/automatic.conf and it reboots only when the transaction it applied requires it. when-changed reboots after any package change, and never is the default. reboot_command controls how, and its default gives logged-in users a five minute warning. Only enable this on a machine whose boot you can recover, because an unattended reboot on a VPS with no console access is a hard failure mode.

Does needs-restarting see processes inside containers?

Not usefully. It matches running processes against the host RPM database, and packages inside a container image are not in that database, so an outdated library baked into an image will not appear. Rebuild the image and redeploy it. The host side still matters: the container runtime and the kernel it shares are host packages, and those do show up.