How to Enable and Configure Automatic Security Updates on Fedora

Install dnf-automatic and enable its timer to get automatic security updates on Fedora.

The quiet threat of unpatched systems

You just read a security advisory about a critical vulnerability in a library your desktop depends on. You want the patch applied automatically, but you also remember the last time an unattended update broke your build environment or changed a kernel parameter. You need a middle ground. You want security patches applied in the background, but you want control over what actually gets installed and when.

How Fedora handles unattended updates

Fedora does not ship with automatic updates enabled by default. The philosophy is simple. The user decides when the system changes. That keeps development environments stable and prevents surprise reboots on headless servers. The mechanism behind unattended updates is dnf-automatic. It is a timer-driven service that checks for updates, downloads them, and optionally applies them. It runs inside a systemd timer, which means it wakes up on a schedule, runs the dnf transaction, logs the result, and goes back to sleep.

The service does not replace your package manager. It uses the exact same repositories, dependency resolver, and transaction journal. If a package conflicts or a repository is unreachable, dnf-automatic fails gracefully and leaves your system untouched. The updates are applied as atomic transactions. You can always roll back to the previous state if something goes wrong. The timer uses a randomized delay to avoid hitting the mirrors at the exact same moment as every other Fedora machine. That prevents mirror overload and keeps download speeds consistent.

Check the package manager history before you trust automation. Run dnf history to see how dnf tracks every transaction. Each update gets a unique ID, a timestamp, and a list of installed or removed packages. If an automatic update breaks a dependency, you can reverse it with sudo dnf history undo <ID>. Trust the package manager. Manual file edits drift, snapshots stay.

Install and activate the timer

Here is how to set up the base service and schedule it to run daily.

sudo dnf install -y dnf-automatic # Pulls the timer unit, service unit, and configuration files
sudo systemctl enable --now dnf-automatic.timer # Enables the daily schedule and starts the scheduler immediately

The --now flag tells systemd to enable the timer for future boots and start it right away. The timer will wake up once a day at a randomized time. The randomization prevents thundering herd problems when thousands of machines check for updates simultaneously.

Verify the timer is active with systemctl list-timers dnf-automatic.timer. The output shows a NEXT column with a timestamp. If the timer just started, the next run will be roughly twenty-four hours away. Reboot before you debug. Half the time the symptom is gone.

Configure what gets updated

The default configuration is conservative. It downloads updates but does not apply them. You need to edit the main configuration file to change that behavior. Always edit the file in /etc/. The package ships a reference copy in /usr/lib/, but you should never modify files in /usr/lib/. Package upgrades will overwrite /usr/lib/ and erase your changes.

Open /etc/dnf/automatic.conf in your editor. The file uses standard INI syntax. Here is a safe baseline for a desktop or workstation that wants security patches applied automatically.

[commands]
# Controls whether dnf downloads updates or just checks for them
upgrade_type = default
# Set to true to automatically install downloaded updates
apply_updates = true
# Set to true to download updates even if they won't be applied immediately
download_updates = true
# Sends an email to root when updates are applied or fail
email_to = root
# Controls whether the system reboots after a kernel update
reboot_window = 0

The upgrade_type setting accepts three values. default pulls all available updates. security restricts the transaction to packages flagged with security advisories. minimal pulls only the smallest set of packages needed to fix dependencies. For most desktop users, security is the safest choice. It keeps your system patched against known exploits without pulling in major library version bumps that might break proprietary software or custom toolchains.

Change upgrade_type = default to upgrade_type = security if you only want critical patches. Save the file and reload the systemd daemon so it picks up the new configuration.

sudo systemctl daemon-reload # Tells systemd to rescan unit files and configuration
sudo systemctl restart dnf-automatic.timer # Restarts the scheduler with the new settings

The reboot_window setting controls automatic reboots. A value of 0 disables automatic reboots entirely. You can set it to 1 to allow reboots only when the system is idle, or 2 to force a reboot regardless of activity. Leave it at 0 for workstations. You do not want a background update interrupting a compilation or a video call. Run journalctl -xe first. Read the actual error before guessing.

Verify the timer and check the logs

Systemd timers are not cron jobs. They use a different scheduling backend and log their output to the journal. Check whether the timer is active and see when it will run next.

systemctl list-timers dnf-automatic.timer # Shows next run time and last trigger
systemctl status dnf-automatic.timer # Confirms the unit is enabled and active

The output will show a NEXT column with a timestamp. If the timer just started, the next run will be roughly twenty-four hours away. You can force an immediate run to test the configuration without waiting.

sudo systemctl start dnf-automatic.timer # Triggers the scheduled job right now
journalctl -xeu dnf-automatic.timer # Reads the journal with explanatory context and jumps to the end

The journalctl -xeu command is the standard way to inspect service output. The x flag adds high-level explanations to error codes, and the e flag skips straight to the most recent entries. Look for lines that say Transaction test succeeded followed by Running transaction. If you see Error: Transaction test error, the resolver found a conflict and aborted. The system is safe.

Check the transaction history to confirm the packages were actually installed.

sudo dnf history list # Shows a numbered list of all package manager transactions
sudo dnf history info <ID> # Displays the exact packages installed or removed in that transaction

The history command gives you a permanent record of what changed. If an update introduces a regression, you can trace it back to the exact transaction ID. Snapshot the system before the upgrade. Future-you will thank you.

Common pitfalls and what the error looks like

Automatic updates can fail for predictable reasons. The most common issue is a repository metadata mismatch. If you added a third-party repository like RPM Fusion or Flatpak, dnf might refuse to apply updates because of a GPG key mismatch or a broken dependency chain. The journal will print Error: GPG check FAILED or Problem: package requires ... but it is not installable.

Another frequent problem is the dnf transaction lock. If you have a terminal window open with dnf upgrade running, the automatic timer will wait and then exit with Another app is currently holding the dnf lock. This is intentional. dnf uses a file lock at /var/run/dnf.pid to prevent concurrent transactions. Close the other terminal or wait for it to finish.

SELinux does not interfere with dnf-automatic. The service runs under the dnf_t domain and has full permission to write to /var/lib/dnf and /var/cache/dnf. If you see an AVC denial in journalctl -t setroubleshoot, it is almost certainly related to a custom script or a misconfigured third-party repository, not the automatic update service itself.

Keep your repository metadata fresh. Run sudo dnf upgrade --refresh once a week in a manual terminal. The --refresh flag forces dnf to ignore cached metadata and download the latest repository headers. Stale metadata causes false dependency conflicts that block automatic updates. If the boot menu is gone, GRUB rescue is your friend, not your enemy.

When to use automatic updates versus manual control

Use dnf-automatic with upgrade_type = security when you want critical patches applied without daily terminal maintenance. Use upgrade_type = default when you run a throwaway VM or a container host where stability matters less than having the latest packages. Use manual dnf upgrade --refresh when you manage a development workstation and need to test new library versions before they hit production. Use dnf system-upgrade when you are crossing major Fedora releases and need to download the full set of packages before rebooting into the new version. Stay on the upstream Workstation defaults if you only deviate from the base system occasionally and prefer to review changelogs manually.

Where to go next