Automatic patching matters most on the systems you do not babysit every day. If you need to configure unattended upgrades on Ubuntu, the built-in unattended-upgrades package can install security fixes in the background, keep a clear log of what changed, and reboot only when your policy allows it.
The same workflow works on Ubuntu 26.04 (Resolute Raccoon), 24.04 (Noble Numbat), and 22.04 (Jammy Jellyfish). Many Ubuntu installs already have the package enabled, while minimal images, cloud instances, and containers are the cases most likely to need a manual install or a quick check of /etc/apt/apt.conf.d/20auto-upgrades.
Install and Enable Unattended Upgrades on Ubuntu
Start by refreshing APT metadata, checking whether Ubuntu already has automatic security updates enabled, and writing the small 20auto-upgrades file directly if you need to turn the feature on.
Update package metadata on Ubuntu
Refresh the package index before you inspect or install anything:
sudo apt update
These commands use
sudobecause they change system package settings. If your account does not have sudo access yet, follow the guide to add a new user to sudoers on Ubuntu before continuing.
Check whether unattended-upgrades is already enabled on Ubuntu
Many Ubuntu systems already have unattended-upgrades present, so check the package state first instead of assuming you need to install it:
dpkg -s unattended-upgrades | grep -E '^(Status|Version):'
On a standard system, you should see output similar to this:
Status: install ok installed Version: 2.12ubuntu7
Ubuntu 24.04 and 22.04 report older package versions, but the package status line should still read install ok installed. If the command prints nothing or reports that the package is missing, install it in the next step. If the grep -E filter is unfamiliar, the guide to the grep command in Linux with examples breaks down how the pattern works.
The package being present is only half the story. Ubuntu also uses /etc/apt/apt.conf.d/20auto-upgrades to decide whether automatic runs are enabled:
cat /etc/apt/apt.conf.d/20auto-upgrades
When unattended upgrades are enabled, the file looks like this:
APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1";
If both values are 1, Ubuntu is already set to refresh package lists and run unattended upgrades automatically. Values of 0, or a missing file, mean you need to enable the feature manually.
Install unattended-upgrades on Ubuntu if it is missing
Install the package only when the package check above shows it is absent:
sudo apt install unattended-upgrades
That is most common on minimal images and containers. On systems where the package is already present, apt will simply report that unattended-upgrades is already the newest version.
Enable automatic security updates on Ubuntu
If 20auto-upgrades is missing or set to 0, write the file directly with these values:
printf '%s\n' 'APT::Periodic::Update-Package-Lists "1";' 'APT::Periodic::Unattended-Upgrade "1";' | sudo tee /etc/apt/apt.conf.d/20auto-upgrades > /dev/null
The sudo tee form matters here because shell redirection does not inherit sudo. It writes the root-owned file directly instead of leaving you with a permission error from a plain > redirect.
Confirm the file contains the enabled values:
cat /etc/apt/apt.conf.d/20auto-upgrades
Expected output:
APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1";
Verify unattended-upgrades status and timers on Ubuntu
Check the shutdown helper service first:
systemctl status unattended-upgrades --no-pager
You should see the service loaded and active:
● unattended-upgrades.service - Unattended Upgrades Shutdown
Loaded: loaded (/usr/lib/systemd/system/unattended-upgrades.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-03-20 13:47:29 AWST
This service is the shutdown helper that waits for package work to finish cleanly during reboot or poweroff. The scheduled upgrade runs themselves come from the APT timers below, not from manually restarting this helper.
Now check the timers that actually schedule refreshes and upgrade runs:
systemctl list-timers apt-daily.timer apt-daily-upgrade.timer --all
Expected output looks similar to this:
NEXT LEFT LAST PASSED UNIT ACTIVATES Fri 2026-03-20 13:54:30 AWST 9min Mon 2026-03-16 07:56:13 AWST - apt-daily-upgrade.timer apt-daily-upgrade.service Fri 2026-03-20 17:18:58 AWST 3h 34min Thu 2026-03-05 11:09:33 AWST - apt-daily.timer apt-daily.service
apt-daily.timer refreshes package metadata, while apt-daily-upgrade.timer runs the unattended upgrade pass. Exact times vary because Ubuntu randomizes the schedule to avoid mirror stampedes.
Configure Unattended Upgrades on Ubuntu
The main configuration lives in /etc/apt/apt.conf.d/50unattended-upgrades. You do not need to replace the whole file. Most changes come down to uncommenting one or two lines and adjusting a few values that match your maintenance policy.
Review the default Allowed-Origins policy on Ubuntu
Ubuntu still uses the Allowed-Origins block, and the default file looks like this on 26.04, 24.04, and 22.04:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
That default is more conservative than it first appears. Ubuntu keeps the main release pocket and the -security pocket enabled so security fixes can pull required dependencies from the base release, while -updates, -proposed, and -backports stay off until you uncomment them. The ESM lines are harmless on systems that are not enrolled in Ubuntu Pro.
Expand automatic updates beyond security patches on Ubuntu
If you also want routine stable updates installed automatically, uncomment the -updates line and keep the rest of the default block intact:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
"${distro_id}:${distro_codename}-updates";
};
On Ubuntu, unattended-upgrades installs security fixes by default and only moves into routine stable updates when you uncomment the -updates line. Leave -proposed and -backports disabled on production hosts unless you have a specific testing reason to pull them in automatically.
Blacklist packages that need a maintenance window on Ubuntu
Use Package-Blacklist when an automatic restart or package replacement would interrupt a service you prefer to patch by hand:
Unattended-Upgrade::Package-Blacklist {
"postgresql-*";
"nginx";
"linux-image-*";
};
This is useful for database clusters, pinned kernels, and web stacks that still need a human check before they bounce. If the host is internet-facing, keep those manually patched packages behind a firewall and pair them with the guide to set up UFW on Ubuntu so the maintenance window does not become your only line of defense.
Configure automatic reboots for unattended-upgrades on Ubuntu
Leave automatic reboots off on workstations or stateful servers, or set a maintenance window when rebooting unattended is acceptable:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";
Automatic-Reboot only matters when an installed update actually requires a restart. Automatic-Reboot-WithUsers "false" is the safer default on shared systems because it skips the reboot when someone is still logged in.
Add mail reports for unattended-upgrades on Ubuntu
Email reports are useful when a server should patch itself quietly but you still want a trail of what changed:
Unattended-Upgrade::Mail "ops@example.com";
Unattended-Upgrade::MailReport "on-change";
on-change is the practical default because it reports real activity without filling your inbox on quiet days. Make sure the host already has a working mail transfer agent before you rely on these notifications.
Use OnlyOnACPower with unattended-upgrades on Ubuntu
The OnlyOnACPower setting depends on the on_ac_power helper. Check whether the command already exists before you install anything extra:
command -v on_ac_power || echo "powermgmt-base required"
On a standard Ubuntu system, you should see:
/usr/sbin/on_ac_power
If the command is missing on a stripped-down image, install the package that provides it:
sudo apt install powermgmt-base
Then enable the AC-power check in 50unattended-upgrades:
Unattended-Upgrade::OnlyOnACPower "true";
Check Unattended-Upgrades Logs on Ubuntu
Ubuntu writes unattended-upgrades activity to its own log directory, which is usually the fastest place to confirm whether a run finished, stalled, or skipped an install.
Find unattended-upgrades log files on Ubuntu
List the available log files first:
ls -1 /var/log/unattended-upgrades
Expected output:
unattended-upgrades-dpkg.log unattended-upgrades-shutdown.log unattended-upgrades.log unattended-upgrades.log.1.gz
unattended-upgrades.log is the high-level run log, unattended-upgrades-dpkg.log records package operations, and unattended-upgrades-shutdown.log is the file to check when shutdown waits for the helper process to exit.
Read recent unattended-upgrades activity on Ubuntu
Tail the main log when you want to confirm what the last run actually did:
sudo tail -n 20 /var/log/unattended-upgrades/unattended-upgrades.log
A dry-run or quiet successful pass often ends with lines like these:
2026-03-20 13:45:59,281 DEBUG left to upgrade set() 2026-03-20 13:45:59,281 INFO All upgrades installed 2026-03-20 13:45:59,428 DEBUG InstCount=0 DelCount=0 BrokenCount=0 2026-03-20 13:45:59,428 INFO The list of kept packages can't be calculated in dry-run mode.
For live log-following techniques beyond a quick tail, see the guide to the tail command in Linux.
Troubleshoot Unattended Upgrades on Ubuntu
Most unattended-upgrades problems come down to a shutdown helper waiting on package work, or an APT lock left behind by another package manager process.
Fix “waiting for unattended-upgr to exit” on Ubuntu
The message about waiting for unattended-upgr to exit comes from unattended-upgrades.service, which is the shutdown helper shown earlier as Unattended Upgrades Shutdown. In most cases, Ubuntu is simply waiting for package work to finish cleanly before powering off.
If the wait clears within a few minutes, let it finish. If it repeats for much longer than expected, inspect /var/log/unattended-upgrades/unattended-upgrades-shutdown.log and then continue with the lock-file check below, because a stale apt or dpkg process is the more common root cause.
Fix dpkg lock errors during unattended-upgrades on Ubuntu
When unattended-upgrades cannot proceed because APT is already busy, identify which process owns the frontend lock:
sudo fuser -v /var/lib/dpkg/lock-frontend
Expected output looks like this when another package tool is still active:
USER PID ACCESS COMMAND
/var/lib/dpkg/lock-frontend:
root 1234 F.... apt
If the command shows a live apt, dpkg, or Software Updater process, let it finish before you try again. When the previous run was interrupted and the lock holder is gone, repair the package database with:
sudo dpkg --configure -a
The same logic applies to /var/lib/apt/lists/lock. If the error points there instead, another package list refresh is already in progress.
Disable or Remove Unattended Upgrades on Ubuntu
Disabling unattended-upgrades and removing the package are two different jobs. The safest path is usually to turn the automatic runs off first and keep the package installed until you are sure you no longer need it.
Disable unattended-upgrades on Ubuntu without removing the package
Set both APT periodic values to 0 when you want scheduled refreshes and unattended installs to stop:
printf '%s\n' 'APT::Periodic::Update-Package-Lists "0";' 'APT::Periodic::Unattended-Upgrade "0";' | sudo tee /etc/apt/apt.conf.d/20auto-upgrades > /dev/null
Verify the disabled state immediately:
cat /etc/apt/apt.conf.d/20auto-upgrades
Expected output:
APT::Periodic::Update-Package-Lists "0"; APT::Periodic::Unattended-Upgrade "0";
This is the setting that stops scheduled unattended runs. Disabling unattended-upgrades.service on its own only affects the shutdown helper, while the scheduled upgrade path still comes from apt-daily-upgrade.timer and /usr/lib/apt/apt.systemd.daily install.
Purge unattended-upgrades from Ubuntu
If you want the package gone completely, remove it first and then purge its generated configuration files:
sudo apt remove unattended-upgrades
sudo apt autoremove
That removes the package itself, but dpkg leaves it in the rc state and keeps 20auto-upgrades and 50unattended-upgrades on disk. If you also want those files deleted, purge the package after the remove step:
sudo apt purge unattended-upgrades
Check that the package is no longer installed:
dpkg -l unattended-upgrades | grep '^ii'
If the command returns no output, the package itself is gone. To confirm the purge also removed the generated configuration files, run:
test ! -e /etc/apt/apt.conf.d/20auto-upgrades && test ! -e /etc/apt/apt.conf.d/50unattended-upgrades && echo "config files removed"
Expected output after a full purge:
config files removed
Unattended Upgrades on Ubuntu FAQ
Usually yes on standard Ubuntu 26.04, 24.04, and 22.04 installs, but minimal images and containers can differ. Check /etc/apt/apt.conf.d/20auto-upgrades; if both APT::Periodic values are set to 1, automatic runs are enabled.
That message comes from the shutdown helper service unattended-upgrades.service. It usually means Ubuntu is finishing package work before poweroff; if it keeps repeating, inspect /var/log/unattended-upgrades/unattended-upgrades-shutdown.log and check for an active apt or dpkg lock.
By default Ubuntu keeps the main release pocket and the -security pocket enabled so security fixes can pull required dependencies. Uncomment the -updates line only when you also want routine stable updates installed automatically.
None in practice. /usr/bin/unattended-upgrades is a symlink to /usr/bin/unattended-upgrade, so either command starts the same program.
Conclusion
Unattended upgrades on Ubuntu are now configured to match your patch window, package blacklist, and reboot policy instead of relying on whatever the default install happened to leave behind. If the host is exposed to the internet, set up UFW on Ubuntu before you leave it unattended. Then install Fail2ban on Ubuntu so automatic patching is backed by basic network hardening.
A very good explanation of unattended-upgrades.
This command and comment will not do what is described:
” sudo tail -n 50 /var/log/syslog | grep unattended-upgrades
This command will display the last 50 entries in the syslog file that contain the “unattended-upgrades” keyword.”
The results will be any entries for unattended-upgrades that appeared in the last 50 lines of syslog.
To get what the description is describing, the grep operation needs to be applied to the log file, then run the tail command.
” sudo grep unattended-upgrades /var/log/syslog | tail -n 50″
Thanks for catching that, Neil! You’re absolutely right. The original command piped to grep was filtering the last 50 lines of syslog first, which could miss relevant entries if they weren’t in that tail window. Your corrected version (
sudo grep unattended-upgrades /var/log/syslog | tail -n 50) properly searches the entire syslog first, then displays the last 50 matching entries.I’ve updated the article to prioritize the dedicated log files in
/var/log/unattended-upgrades/(unattended-upgrades.log and unattended-upgrades-dpkg.log) since they provide better signal without needing to grep through general syslog noise. The revised section now uses journalctl for more efficient searching. Appreciate you taking the time to point this out!whatever is responsible for formatting the comments seems to have also changed my posts n dashed to m dashes on post. Tying HTML codes.
… instead of the double n dashes ( (--) ) …
e.g. … instead of ” (--)dry-run.
The last 4 items of the “Configure Unattended Upgrades” options table have a formatting error (that some editing program probably forced on you) and are currently starting with a longer single m dash (–) instead of the double n dashes (–) the options should be predicated with to be options, e.g. The table has “–dry-run” instead of “–dry-run.”
Thanks for spotting that, Alexander! You’re right about the dash encoding issue. The WordPress’s visual editor sometimes converts double hyphens into em dashes during paste operations. I’ve reviewed the options table and corrected any instances where
--dry-run,--download-only,--minimal-upgrade-steps, and--no-minimal-upgrade-stepswere displaying with incorrect dash characters. The commands now show proper double hyphens throughout. Appreciate the sharp eye!Seems you don’t need a cron job on Ubuntu >= 22.04 (or even earlier, did not check this), as this is already managed by “apt-daily-upgrade.timer” (`systemctl list-timers –all | grep apt`).
Exactly right, flederwiesel! Ubuntu has used systemd timers (
apt-daily.timerandapt-daily-upgrade.timer) as the default scheduling mechanism since at least 16.04. The article covers this in the “Understanding Automatic Update Scheduling” section, explaining that the systemd timers handle everything automatically after installation. The cron job section is marked as optional and only needed when users want precise control over timing or need to integrate with existing cron-based workflows. Most users should stick with the default systemd timers and skip manual cron configuration entirely.Thanks for highlighting this, it’s an important distinction!
> This command will display the last 50 entries in the syslog file that contain the “unattended-upgrades” keyword.
Not true. This command will display from the last 50 entries in the syslog file those that contain the “unattended-upgrades” keyword, which is a subtle difference. 😉
Did you mean `sudo grep unattended-upgrades /var/log/syslog |tail -n 50`?
Good catch, flederwiesel! You’re absolutely right about the difference, piping tail output to grep only searches within those last 50 lines, not across the entire log. Your corrected version (
sudo grep unattended-upgrades /var/log/syslog | tail -n 50) properly searches the full syslog first, then shows the last 50 matches. I’ve updated the article to prioritize the dedicated log files in/var/log/unattended-upgrades/and use journalctl for more efficient searching, which avoids this grep/tail ordering issue entirely.Thanks for the detailed explanation!
should be
sudo unattended-upgrade
not the plural
Thanks for catching that, mark! You’re correct, i made an typo mistake, which is corrected.
Unfortunately, after installing Ubuntu 24.04 LTS, my resolution has been reset to 800 x 600, and I am unable to change it back.
Hi Josef, that sounds like a graphics driver issue rather than an unattended-upgrades problem. The resolution being locked at 800×600 typically means Ubuntu fell back to generic VESA drivers instead of loading your GPU’s native driver. Try running
ubuntu-drivers devicesto see what’s available, thensudo ubuntu-drivers autoinstallto install the recommended driver.After a reboot, your proper resolution options should return.
Hi, there’s a typo in this line, enable is missing the L. Thanks for the guide!
Enable on boot the unattended services:
sudo systemctl enabe unattended-upgrades
Thanks, typo is fixed.