The scenario
You leave your Fedora workstation running overnight. By morning, a critical CVE drops for a core library. You could manually run sudo dnf upgrade --refresh every week, or you could let the system handle it. If you want security patches applied without logging in, dnf-automatic is the standard tool. The default configuration is conservative. It downloads updates but does not install them. You need to change that behavior to get true unattended patching.
How the timer and service split the work
dnf-automatic is not a background daemon that watches the network. It is a systemd timer that wakes up once a day, runs a script, and goes back to sleep. The timer handles the clock. The service handles the work. The configuration file handles the rules.
Think of it like a scheduled maintenance window. The dnf-automatic.timer checks the system clock at a randomized interval. When the time comes, it triggers dnf-automatic.service. The service reads /etc/dnf/automatic.conf to decide what to do. If the configuration says apply_updates = no, the system will only check for new packages and email you a report. Change that flag to yes, and the transaction runs automatically. The package manager resolves dependencies, downloads the RPMs, and applies the transaction. If the transaction requires a reboot, the service can trigger it, but only if you explicitly allow it.
Run systemctl status dnf-automatic.timer first. Read the actual error before guessing.
Install and enable the scheduler
The package is not installed by default on minimal or server spins. You need to pull it in and activate the timer. The timer uses a randomized delay to prevent all machines on a network from hammering the mirrors at the exact same second.
Here's how to install the package and start the scheduler immediately.
sudo dnf install dnf-automatic
# Pulls the package from the configured repositories
# Verifies GPG signatures before unpacking
# Places the timer and service units in /usr/lib/systemd/system
sudo systemctl enable --now dnf-automatic.timer
# Enables the timer to start on boot
# Starts the timer immediately so you do not wait for the next boot cycle
# The --now flag combines enable and start in one transaction
The timer will now wake up daily. The default delay is randomized between 0 and 3600 seconds. This spreads the load across the mirror network. You can change the delay in the configuration file if your network has strict bandwidth windows.
Enable the timer before you edit the configuration. The service will not run until the timer fires.
Configure the update behavior
The configuration file lives in /etc/dnf/automatic.conf. Never edit files in /usr/lib/. Those ship with the package and get overwritten on upgrade. Always edit /etc/. The system merges /etc/ overrides with the package defaults.
Here's how to set up unattended security updates with email notifications.
# /etc/dnf/automatic.conf
# Controls what dnf-automatic does when the timer fires
[commands]
# Determines whether downloaded packages are actually installed
# Set to yes for true unattended patching
apply_updates = yes
# Controls whether the system reboots after a kernel or critical update
# Leave as no unless you are running a headless server with no active sessions
upgrade_kernel = yes
reboot = no
# Limits updates to security advisories only
# Change to default if you want all package updates applied automatically
upgrade_type = security
# Sends a summary email after the run completes
# Requires a local MTA like postfix or sendmail to be configured
email_to = root
The upgrade_type = security setting is the safest starting point. It applies only packages marked with a security advisory. The apply_updates = yes flag is what actually runs the transaction. Without it, the service only downloads and reports. The reboot = no setting prevents unexpected downtime on desktop systems. Change it to yes only for headless servers where you can tolerate a scheduled restart.
Edit the configuration file before the next timer run. The service reads the file fresh every time it wakes up.
Verify the system is patching itself
The timer runs in the background. You need to check the logs to confirm it actually applied updates. The journalctl command shows the service output and any dependency resolution warnings.
Here's how to check whether the last run succeeded and what it installed.
journalctl -xeu dnf-automatic.service
# The -x flag adds explanatory context to error lines
# The -e flag jumps to the end of the log
# The -u flag filters only the dnf-automatic service unit
# Shows the exact transaction ID and package list
You will see lines like Installed: 3 packages or No updates available. If the service failed, the log will show the exact DNF error. Check the status output to confirm the timer is active and scheduled.
systemctl status dnf-automatic.timer
# Shows the next scheduled run time
# Confirms the timer is loaded and active
# Displays the last trigger time and service exit code
If the exit code is 0, the run succeeded. If it is 1 or higher, read the journal output for the specific DNF error. Do not restart the timer manually. Let it run on its own schedule.
Run journalctl -xeu dnf-automatic.service first. Read the actual error before guessing.
Common pitfalls and what the logs will show
Unattended updates interact with dependency resolution, SELinux, and network configuration. The logs will tell you exactly where the process stopped.
The dnf-automatic service will refuse to proceed and print Error: Transaction test error: package python3-3.12.x conflicts with python3-3.13.y. The conflict is intentional. Read the next paragraph before forcing. DNF protects the system from breaking transactions. If you see a conflict, the automatic run will abort. You need to resolve it manually with sudo dnf upgrade --refresh. The automatic timer will skip the broken transaction and wait for the next day.
If you see [FAILED] Failed to start dnf-automatic.service during the timer trigger, your network configuration probably references a missing interface name or the mirror list is unreachable. Check your DNS and gateway. The service cannot resolve repository URLs without a working network stack.
SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. The dnf-automatic service runs in the dnf_t domain. If you modified the script path or moved the configuration file, SELinux will block the transaction. Restore the default context with restorecon -v /etc/dnf/automatic.conf and try again.
The timer will not run if the system is suspended. Wake the machine before the scheduled window. The systemd timer checks the real-time clock, not the uptime.
Check the journal output before changing configuration flags. Half the time the symptom is a transient network timeout.
When to use dnf-automatic versus manual upgrades
Use dnf-automatic when you want security patches applied daily without logging into the machine. Use sudo dnf upgrade --refresh when you need to review package changelogs before applying changes. Use dnf system-upgrade when you are crossing major Fedora releases like 40 to 42. Use manual updates when you run a desktop environment and want to control reboot timing. Stay on the default upgrade_type = security if you only want critical CVE fixes applied automatically. Switch to upgrade_type = default when you run a homelab server and want every package updated on the same schedule.
Trust the package manager. Manual file edits drift, snapshots stay.