Enable and Verify unattended-upgrades on Debian Stable
Enable unattended-upgrades on Debian stable so security patches install automatically: configuration, systemd timers, dry-run validation, log checks, and recovery from interrupted runs.
27 Apr 2026, 03:21 UTC

The problem and the outcome
A Debian server that only gets patched when someone remembers to run apt upgrade accumulates known-vulnerable packages between maintenance windows. The unattended-upgrades package closes that gap: it installs security updates automatically each day while leaving everything else — feature updates, backports, new packages — as a deliberate manual decision. That split is the point: low patch latency for security fixes, full change control for everything else.
This guide covers enabling the feature, constraining what it may install, proving it works before trusting it, and recovering if a run is interrupted. Commands assume Debian 12 (bookworm) or 13 (trixie); the config template shipped with your installed package version is authoritative, since defaults shift between releases.
Prerequisites
- Debian stable with root or sudo access.
- Working network access to a Debian mirror (check
/etc/apt/sources.listor/etc/apt/sources.list.d/debian.sources). - Optional but useful:
apt-listchangesfor change notifications andneedrestartto flag services that must be restarted after library updates.
Note that the Debian installer often enables unattended-upgrades already if you answered yes to the security-updates question. Check before reconfiguring:
dpkg-query -W -f="${Status}\n" unattended-upgradesIf it reports install ok installed, skip the install step and go straight to reviewing the configuration.
Install and enable the daily run
As root (or via sudo):
apt-get update
apt-get install unattended-upgradesThen enable the daily cycle. Either run the interactive prompt:
dpkg-reconfigure -plow unattended-upgradesor create /etc/apt/apt.conf.d/20auto-upgrades directly:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";The first line refreshes package lists daily; the second permits automatic installation. Pick one method and stick with it — mixing dpkg-reconfigure with hand edits to the same files can produce conffile prompts on later package upgrades.
Constrain what gets installed
Review /etc/apt/apt.conf.d/50unattended-upgrades. The key section is the origins allowlist. Keep the security origin enabled, which looks like:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};Leave backports and proposed-updates commented out. Enabling the -updates origin widens the automatic change set beyond security fixes; that can be a legitimate policy, but make it an explicit, documented choice rather than an accident of an uncommented line.
Three other options deserve a deliberate decision:
Unattended-Upgrade::Mail— silent unless a working MTA is configured. Verify actual delivery with a test message; setting the option alone proves nothing.Unattended-Upgrade::Remove-Unused-Dependencies— handy for keeping systems tidy, but it can remove packages you installed manually that nothing else depends on.Unattended-Upgrade::Automatic-Reboot— if enabled, setAutomatic-Reboot-Timeto a maintenance window (e.g."03:30"). An arbitrary-time reboot will eventually interrupt something important. Keeping reboots manual is a defensible default.
How it actually runs
Two systemd timers drive the process: apt-daily.timer downloads package lists and packages, and apt-daily-upgrade.timer performs the installation. Both apply a randomized delay so a fleet of machines does not hit mirrors simultaneously, and a lock prevents overlap with a manual apt run — if you run apt upgrade yourself, the timer simply waits or defers.
Prove it works before trusting it
Run these as root or with sudo:
1. Confirm the timers are scheduled:
systemctl list-timers apt-daily*You should see both timers with a NEXT time. 2. Confirm the apt configuration took effect:
apt-config dump APT::PeriodicBoth values should read "1". 3. Preview behavior without changing anything — note the binary name is singular:
unattended-upgrade --dry-run --debugThis completes without installing anything and shows exactly which pending packages match the security origin and which are skipped. If it identifies packages you did not expect, revisit your origins allowlist before going further. 4. After the next scheduled run, check the log:
less /var/log/unattended-upgrades/unattended-upgrades.logA healthy run ends with a summary of packages upgraded (or "No packages found that can be upgraded unattended"). Comparing apt list --upgradable before and after a scheduled run is the strongest end-to-end check: security updates should disappear from the list on their own.
Recovery from an interrupted run
If the machine loses power or reboots mid-upgrade, dpkg can be left with half-configured packages. First confirm nothing is still running:
ps aux | grep -E 'apt|dpkg|unattended' | grep -v grepOnly when no apt or dpkg process is active, repair the package state:
dpkg --configure -a
apt-get -f installThen re-check with apt list --upgradable. Never delete dpkg lock files (/var/lib/dpkg/lock*) while any package process might be alive — a stale lock is rare, and removing a live one corrupts the package database.
The follow-up automation cannot do for you
Automatic installation does not mean automatic activation. A new kernel or an updated OpenSSL only takes effect after a reboot or service restart. Install needrestart and check it after upgrade runs, or watch for the reboot-required indicator at /var/run/reboot-required. Without that step, the system reports fully patched while still running the vulnerable code — a false sense of currency that is worse than an honest backlog.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.