Skip to content
← All posts

guides

RHEL Patching Step by Step: dnf, dnf-automatic and Security-Only Updates

October 10, 2026

To patch RHEL, confirm the system is registered, list pending advisories with dnf updateinfo list --security, apply them with dnf upgrade --security, then run dnf needs-restarting -r to see whether a reboot is due. dnf-automatic repeats that on a timer. The same commands work on Rocky Linux and AlmaLinux 8, 9 and 10.

This is the process for patching a Red Hat Enterprise Linux server, written as commands in the order you run them. It applies to RHEL 8, 9 and 10 and, unchanged, to Rocky Linux and AlmaLinux, because all of them use dnf and publish security advisories in the same format. It ends with how to automate the routine and where a single host’s process stops being enough for a fleet.

The commands at a glance

StepCommandWhat it tells you or does
1. Check the subscription and repossubscription-manager status, dnf repolistWhether the host can see updates at all
2. List pending security advisoriesdnf updateinfo list --securityEach RHSA and the package it fixes
3. Apply security updates onlydnf upgrade --securityInstalls fixes for published advisories
4. Patch one CVE or advisorydnf upgrade --cve CVE-… / --advisory RHSA-…A targeted fix ahead of the window
5. Check for a rebootdnf needs-restarting -rExit 1 if the kernel or a core library changed
6. Record or undo the changednf history, dnf history undo <id>The audit record and the rollback
7. Automate itdnf-automatic-install.timerThe same steps on a schedule

Step 1: Confirm the host can see updates

A RHEL server that is not registered, or whose repositories are disabled, reports “nothing to do” and looks fully patched. Check before you trust any later output:

sudo subscription-manager status       # "Overall Status: Registered" (or Simple Content Access)
sudo dnf repolist                      # BaseOS and AppStream must be listed
sudo dnf makecache                     # refresh metadata now instead of waiting for the timer

On Rocky Linux and AlmaLinux there is no subscription step; dnf repolist is enough. Hosts behind a proxy or pointed at an internal mirror are the usual source of stale results, so check that the mirror itself was synced recently.

Step 2: See what is pending, by severity

dnf reads Red Hat’s advisory metadata (updateinfo), which tags every update as a security advisory (RHSA), a bug fix (RHBA) or an enhancement (RHEA), each with a severity.

sudo dnf updateinfo summary                            # counts by type and severity
sudo dnf updateinfo list --security                    # every pending security advisory
sudo dnf updateinfo list --security --sec-severity=Critical
sudo dnf updateinfo info RHSA-2026:1234                # the advisory text, CVEs and packages
sudo dnf check-update --security; echo $?              # exit 100 when updates are pending

The exit code of dnf check-update is the one to use in scripts and monitoring: 100 means updates are available, 0 means none, 1 means an error.

Step 3: Apply security updates only

sudo dnf upgrade --security -y

This installs every package that fixes a published security advisory and leaves bug-fix and enhancement updates for the next full maintenance window. Two variations matter:

  • dnf upgrade-minimal --security moves each package only to the version that fixes the advisory, not to the newest build in the repository. It is the most conservative option for production systems in a change freeze.
  • dnf upgrade --security --sec-severity=Critical --sec-severity=Important limits the run to the two severities most patch policies set deadlines for.

Run the full dnf upgrade on a monthly cadence anyway. Security-only patching keeps the host safe between windows, but a host that never takes bug fixes drifts away from what the vendor tests, and the next security fix eventually depends on a bug fix you skipped.

Step 4: Patch one CVE ahead of the window

When a single CVE is in the news, you do not need to wait for the monthly run:

sudo dnf updateinfo info --cve CVE-2026-12345          # which advisory fixes it, if any
sudo dnf upgrade --cve CVE-2026-12345 -y               # apply just that fix
sudo dnf upgrade --advisory RHSA-2026:1234 -y          # or by advisory ID

If updateinfo finds nothing, Red Hat has either not shipped a fix yet or rated the CVE as not affecting RHEL. The Red Hat CVE page for that ID states which, and is the evidence an auditor will ask for.

Step 5: Decide whether the host needs a reboot

sudo dnf needs-restarting -r; echo $?    # 1 = reboot required, 0 = not required
sudo dnf needs-restarting -s             # services still running old libraries

-r checks the packages whose update only takes effect at boot: the kernel, glibc, systemd, the linux-firmware and a few others. If it returns 0 but -s lists services, a systemctl restart of those services finishes the job without downtime. On RHEL 7 the same command ships in yum-utils as needs-restarting -r.

For kernel CVEs on hosts that cannot reboot on short notice, RHEL’s kernel live patching applies the fix to the running kernel:

sudo dnf install kpatch-dnf
sudo dnf kpatch auto                     # subscribe to live patches for every installed kernel
sudo kpatch list                         # what is loaded now

Live patches cover selected Critical and Important kernel CVEs for a limited time per kernel build. They buy time until the next planned reboot; they do not replace it.

Step 6: Keep the record and know how to undo it

Every dnf transaction is recorded on the host:

sudo dnf history list --reverse | tail     # transaction IDs, dates and who ran them
sudo dnf history info 42                   # packages and versions in transaction 42
sudo dnf history undo 42                   # roll transaction 42 back

dnf history undo works when the previous package versions are still available in the repositories, which is true for RHEL’s own repos and most mirrors. For a package you need to keep at a known version, pin it instead of undoing it every week:

sudo dnf install python3-dnf-plugin-versionlock
sudo dnf versionlock add openssl          # pin the installed version
sudo dnf versionlock list
sudo dnf versionlock delete openssl       # release the pin later

Write the undo command for your riskiest package into the change ticket before you patch. At 2am you will not want to work it out.

Step 7: Automate it with dnf-automatic

dnf-automatic runs steps 2 and 3 on a systemd timer.

sudo dnf install dnf-automatic
sudo vi /etc/dnf/automatic.conf
[commands]
upgrade_type = security      # "default" applies every update
apply_updates = yes
random_sleep = 3600          # spread hosts out so the mirror is not hit at once

[emitters]
emit_via = motd              # or "email" with the [email] section filled in
sudo systemctl enable --now dnf-automatic-install.timer
systemctl list-timers 'dnf-automatic*'

Choose the timer by what you want it to do, because the names are easy to confuse: dnf-automatic-install.timer downloads and installs, dnf-automatic-download.timer only downloads, dnf-automatic-notifyonly.timer only reports, and plain dnf-automatic.timer follows apply_updates in the config file. A common pattern is the install timer with upgrade_type = security on every host, and full upgrades kept for the monthly window.

What dnf-automatic does not do: it never reboots, it does not stagger rollouts between hosts, and its record of what happened lives on each host. That is fine for five servers. It is the point where most teams add a Linux patch management tool on top.

From one host to a fleet

The steps above patch one host well. Across fifty, the questions change: which hosts still have the advisory pending, which ones need a reboot, which ran the update and which failed, and can QA take it a day before production. The three usual answers:

ApproachGood atWhere it stops
dnf-automatic on every hostFree, already installed, security-only by configNo central view, no staging, no reboot coordination
Ansible playbooks wrapping dnfBatching with serial, reboots with the reboot moduleYou build and keep the reporting, CVE context and history
Red Hat SatelliteContent views, lifecycle environments, Red Hat supportRHEL-family hosts only; a server to run; see Satellite alternatives
A cross-distro tool such as SysWardOne view of every host and CVE, grouped rollouts, historyAgent per host; no repository mirroring or content views

SysWard runs the same commands described here. Its agent reads dnf’s security metadata to separate security updates from the rest, applies upgrades from a schedule or on demand, pins packages with versionlock, and reports needs-restarting -r so the dashboard shows which hosts are waiting for a reboot. The Red Hat patch management guide covers the fleet side, and the same workflow runs for Rocky Linux and Ubuntu or SUSE hosts in the same console.

A monthly RHEL patching checklist

  1. Confirm every host is registered and its repositories are current (step 1).
  2. Export pending security advisories by severity and attach them to the change ticket (step 2).
  3. Patch a staging group, run your smoke tests, wait a day.
  4. Apply dnf upgrade (or --security in a freeze) to production in batches (step 3).
  5. Reboot the hosts needs-restarting -r flags, inside the window (step 5).
  6. Save dnf history output, or your tool’s report, as evidence (step 6).
  7. Leave dnf-automatic on for security updates between windows (step 7).

If you also run SUSE hosts, the SUSE patching process with zypper is the same checklist with the zypper commands. To see every RHEL, Rocky and Alma host’s pending advisories in one place, start free with 5 agents, no card required.

Frequently Asked Questions

How do I install only security updates on RHEL?

Run dnf upgrade --security. It installs only the packages that fix a published security advisory (RHSA). Add --sec-severity=Critical or --sec-severity=Important to narrow it further, or use dnf upgrade-minimal --security to move each package only as far as the version that fixes the advisory, not to the newest build.

How do I patch a specific CVE on RHEL?

Use dnf upgrade --cve CVE-YYYY-NNNNN, or dnf upgrade --advisory RHSA-YYYY:NNNN if you have the advisory ID. dnf updateinfo info --cve CVE-YYYY-NNNNN shows which advisory and packages carry the fix before you apply it.

How do I know if RHEL needs a reboot after patching?

Run dnf needs-restarting -r. It exits with 1 and prints "Reboot is required" when a core package such as the kernel, glibc or systemd was updated since the last boot, and exits with 0 otherwise. Without -r it lists processes still running old libraries, which a service restart fixes without a reboot.

Which dnf-automatic timer installs updates?

dnf-automatic-install.timer downloads and installs. dnf-automatic-download.timer only downloads, dnf-automatic-notifyonly.timer only reports, and plain dnf-automatic.timer does whatever /etc/dnf/automatic.conf says, which by default is download without install. Set upgrade_type = security in that file to limit it to security advisories.

Does dnf upgrade --security work on Rocky Linux and AlmaLinux?

Yes. Rocky Linux and AlmaLinux publish their own advisory metadata (RLSA and ALSA), so --security, --advisory and --cve filter correctly. CentOS 7 was the exception: its repositories shipped no advisory metadata, so yum update --security quietly found nothing.

Stop patching Linux servers by hand

SysWard automates patch management across your entire fleet — CVE scanning, scheduled rollouts, and audit-ready reports in one dashboard.

Start free