Skip to main content
  1. Linux Articles/
  2. Ubuntu 26.04 LTS Server/

Configuring Automatic Updates on Ubuntu 26.04 LTS Server (unattended-upgrades)

Table of Contents

Checking and Configuring Automatic Updates

Ubuntu 26.04 LTS Server applies security updates automatically from the moment it is installed. This article explains how to check that mechanism and how to change the update scope, the automatic reboot and the schedule, as well as how to turn it off.

Automatic updates rely on two pieces.

PieceRole
The unattended-upgrades packageApplies the updates. It provides the unattended-upgrade command
systemd timersTrigger the periodic runs: apt-daily.timer (refresh and download) and apt-daily-upgrade.timer (apply)

Checking Whether Automatic Updates Are Enabled

Check that the package is installed and look at /etc/apt/apt.conf.d/20auto-upgrades. Automatic updates are enabled when both values are "1".

Commands to check the automatic update settings
dpkg -l unattended-upgrades
cat /etc/apt/apt.conf.d/20auto-upgrades
Example: checking the automatic update settings
kazulog@sv1:~$ dpkg -l unattended-upgrades | tail -1
ii  unattended-upgrades 2.12ubuntu9  all          automatic installation of security upgrades
kazulog@sv1:~$ cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
kazulog@sv1:~$
SettingMeaning
APT::Periodic::Update-Package-Lists1 runs the equivalent of apt update daily
APT::Periodic::Unattended-Upgrade1 applies updates daily

apt-config dump shows the effective values across all configuration files.

Example: checking the effective values
kazulog@sv1:~$ apt-config dump APT::Periodic
APT::Periodic "";
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::Unattended-Upgrade "1";
kazulog@sv1:~$

The service shown by systemctl status unattended-upgrades is called “Unattended Upgrades Shutdown”: it exists to wait for an in-progress upgrade during shutdown. The periodic runs come from the timers, not from this service, so do not confuse the two.

What unattended-upgrades.service looks like
kazulog@sv1:~$ systemctl status unattended-upgrades --no-pager -l | head -8 | cat
● unattended-upgrades.service - Unattended Upgrades Shutdown
     Loaded: loaded (/usr/lib/systemd/system/unattended-upgrades.service; enabled; preset: enabled)
     Active: active (running) since Thu 2026-09-10 16:18:20 JST; 31s ago
 Invocation: 4c3cdd457ec840ce8982daa12d140003
       Docs: man:unattended-upgrade(8)
   Main PID: 1090 (unattended-upgr)
      Tasks: 2 (limit: 1486)
     Memory: 15M (peak: 15.2M)
kazulog@sv1:~$

Checking the Schedule

systemctl list-timers shows when the timers fire next.

Command to check the timers
systemctl list-timers 'apt-daily*'
Example: checking the timers
kazulog@sv1:~$ systemctl list-timers 'apt-daily*' --no-pager
NEXT                        LEFT LAST                        PASSED UNIT                    ACTIVATES
Fri 2026-09-11 02:45:01 JST  10h Thu 2026-09-10 13:30:25 JST      - apt-daily.timer         apt-daily.service
Fri 2026-09-11 06:05:55 JST  13h Thu 2026-09-10 13:30:25 JST      - apt-daily-upgrade.timer apt-daily-upgrade.service

2 timers listed.
Pass --all to see loaded but inactive timers, too.
kazulog@sv1:~$

systemctl cat shows how a timer is defined.

Example: the timer definition
kazulog@sv1:~$ systemctl cat apt-daily-upgrade.timer | cat
# /usr/lib/systemd/system/apt-daily-upgrade.timer
[Unit]
Description=Daily apt upgrade and clean activities
After=apt-daily.timer

[Timer]
OnCalendar=*-*-* 6:00
RandomizedDelaySec=60m
Persistent=true

[Install]
WantedBy=timers.target
kazulog@sv1:~$
SettingMeaning
OnCalendar=*-*-* 6:00Runs daily at 06:00
RandomizedDelaySec=60mAdds a random delay of up to 60 minutes (so that many servers do not hit the mirrors at once)
Persistent=trueRuns at the next boot if the machine was off at the scheduled time

The random delay is why the next run in the example above is not exactly 06:00.

Checking What Gets Updated

Allowed-Origins in /etc/apt/apt.conf.d/50unattended-upgrades decides which repositories are used.

Command to check the update scope
grep -E 'distro_codename' /etc/apt/apt.conf.d/50unattended-upgrades
Example: checking the update scope
kazulog@sv1:~$ grep -nE 'distro_codename' /etc/apt/apt.conf.d/50unattended-upgrades | head -12
7:	"${distro_id}:${distro_codename}";
8:	"${distro_id}:${distro_codename}-security";
13:	"${distro_id}ESMApps:${distro_codename}-apps-security";
14:	"${distro_id}ESM:${distro_codename}-infra-security";
15://	"${distro_id}:${distro_codename}-updates";
16://	"${distro_id}:${distro_codename}-proposed";
17://	"${distro_id}:${distro_codename}-backports";

Lines beginning with // are comments. By default -updates (non-security updates), -proposed and -backports are excluded, so only security updates are applied automatically.

Running It by Hand

The same work can be triggered manually with unattended-upgrade. The command has no trailing s (the package and the service are unattended-upgrades).

With --dry-run, nothing is changed and you only see what would be selected.

Command to preview the updates (changes nothing)
sudo unattended-upgrade --dry-run -v
Example: previewing the updates
kazulog@sv1:~$ sudo unattended-upgrade --dry-run -v
Starting unattended upgrades script
Allowed origins are: o=Ubuntu,a=resolute, o=Ubuntu,a=resolute-security, o=UbuntuESMApps,a=resolute-apps-security, o=UbuntuESM,a=resolute-infra-security
Initial blacklist: 
Initial whitelist (not strict): 
Option --dry-run given, *not* performing real actions
Packages that will be upgraded: bind9-dnsutils bind9-host bind9-libs bpftool bsdextrautils bsdutils cpio curl diffutils dirmngr eject fdisk gnu-coreutils gnupg gnupg-l10n gnupg-utils gpg gpg-agent gpg-wks-client gpgconf gpgsm gpgv libattr1 libblkid1 libbz2-1.0 libc-bin libc-dev-bin libc-gconv-modules-extra libc6 libc6-dev libcurl3t64-gnutls libcurl4t64 libevent-core-2.1-7t64 libfdisk1 libgcrypt20 liblastlog2-2 libmount1 libpam-modules libpam-modules-bin libpam-runtime libpam0g libperl5.40 libpython3.14 libpython3.14-minimal libpython3.14-stdlib libsmartcols1 libssh2-1t64 libssl3t64 libudisks2-0 libuuid1 linux-headers-generic linux-headers-virtual linux-image-virtual linux-libc-dev linux-perf linux-tools-common linux-virtual locales login mount openssl openssl-provider-legacy perl perl-base perl-modules-5.40 python3-pyasn1 python3.14 python3.14-gdbm python3.14-minimal sudo-rs udisks2 util-linux util-linux-extra uuid-runtime vim vim-common vim-runtime vim-tiny xxd zlib1g
/snip/
All upgrades installed
The list of kept packages can't be calculated in dry-run mode.

Allowed origins are: lists the repositories and Packages that will be upgraded: lists the packages. Drop --dry-run to apply them.

Command to apply the updates
sudo unattended-upgrade -v
Example: applying the updates
kazulog@sv1:~$ sudo unattended-upgrade -v
Starting unattended upgrades script
Allowed origins are: o=Ubuntu,a=resolute, o=Ubuntu,a=resolute-security, o=UbuntuESMApps,a=resolute-apps-security, o=UbuntuESM,a=resolute-infra-security
Initial blacklist: 
Initial whitelist (not strict): 
Packages that will be upgraded: bind9-dnsutils bind9-host bind9-libs bpftool bsdextrautils bsdutils cpio curl diffutils dirmngr eject fdisk gnu-coreutils gnupg gnupg-l10n gnupg-utils gpg gpg-agent gpg-wks-client gpgconf gpgsm gpgv libattr1 libblkid1 libbz2-1.0 libc-bin libc-dev-bin libc-gconv-modules-extra libc6 libc6-dev libcurl3t64-gnutls libcurl4t64 libevent-core-2.1-7t64 libfdisk1 libgcrypt20 liblastlog2-2 libmount1 libpam-modules libpam-modules-bin libpam-runtime libpam0g libperl5.40 libpython3.14 libpython3.14-minimal libpython3.14-stdlib libsmartcols1 libssh2-1t64 libssl3t64 libudisks2-0 libuuid1 linux-headers-generic linux-headers-virtual linux-image-virtual linux-libc-dev linux-perf linux-tools-common linux-virtual locales login mount openssl openssl-provider-legacy perl perl-base perl-modules-5.40 python3-pyasn1 python3.14 python3.14-gdbm python3.14-minimal sudo-rs udisks2 util-linux util-linux-extra uuid-runtime vim vim-common vim-runtime vim-tiny xxd zlib1g
Writing dpkg log to /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
/snip/

No VM guests are running outdated hypervisor (qemu) binaries on this host.
All upgrades installed

Checking Whether a Reboot Is Needed

When a kernel or libc update is applied, a file is created to signal that a reboot is required. Automatic updates do not reboot the machine with the default settings.

Commands to check whether a reboot is needed
ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgs
Example: checking whether a reboot is needed
kazulog@sv1:~$ ls -l /var/run/reboot-required /var/run/reboot-required.pkgs
-rw-r--r-- 1 root root 32 Sep 10 16:37 /var/run/reboot-required
-rw-r--r-- 1 root root 46 Sep 10 16:37 /var/run/reboot-required.pkgs
kazulog@sv1:~$ cat /var/run/reboot-required
*** System restart required ***
kazulog@sv1:~$ head -5 /var/run/reboot-required.pkgs
libc6
linux-image-7.0.0-31-generic
linux-base
kazulog@sv1:~$

The .pkgs file lists the packages that require the reboot.

Reading the Logs

Automatic update logs live in /var/log/unattended-upgrades/.

FileContents
unattended-upgrades.logThe run itself (selected packages, start and finish)
unattended-upgrades-dpkg.logDetailed output from unpacking the packages
unattended-upgrades-shutdown.logRecords of waiting for an upgrade during shutdown
Command to read the log
sudo tail /var/log/unattended-upgrades/unattended-upgrades.log
Example: reading the log
kazulog@sv1:~$ sudo ls -l /var/log/unattended-upgrades/
total 80
-rw-r--r-- 1 root adm  66297 Sep 10 16:38 unattended-upgrades-dpkg.log
-rw-r--r-- 1 root root     0 Sep 10 13:30 unattended-upgrades-shutdown.log
-rw-r--r-- 1 root root  5069 Sep 10 16:38 unattended-upgrades.log

Changing the Settings

Including Non-Security Updates

Uncomment the -updates line in 50unattended-upgrades.

Command to edit the configuration file
sudo vi /etc/apt/apt.conf.d/50unattended-upgrades
Including -updates
Unattended-Upgrade::Allowed-Origins {
	"${distro_id}:${distro_codename}";
	"${distro_id}:${distro_codename}-security";
	"${distro_id}:${distro_codename}-updates";
};

Running --dry-run afterwards shows the larger selection.

Example: the selection after the change
kazulog@sv1:~$ sudo unattended-upgrade --dry-run -v 2>&1 | head -6
Starting unattended upgrades script
Allowed origins are: o=Ubuntu,a=resolute, o=Ubuntu,a=resolute-security, o=UbuntuESMApps,a=resolute-apps-security, o=UbuntuESM,a=resolute-infra-security, o=Ubuntu,a=resolute-updates
Initial blacklist: 
Initial whitelist (not strict): 
Option --dry-run given, *not* performing real actions
Packages that will be upgraded: base-files libaudit-common libaudit1 libflashrom1 motd-news-config python-apt-common python3-apt python3-distupgrade ubuntu-release-upgrader-core

a=resolute-updates is now at the end of Allowed origins are:, and packages that were previously skipped are selected.

Rebooting Automatically After an Update

To reboot automatically when a reboot becomes necessary, add these settings. Writing them to a separate file with a higher number leaves the original file untouched.

Command to configure the automatic reboot
printf 'Unattended-Upgrade::Automatic-Reboot "true";\nUnattended-Upgrade::Automatic-Reboot-Time "03:00";\n' | sudo tee /etc/apt/apt.conf.d/51custom-reboot
SettingMeaning
Automatic-Reboottrue reboots when a reboot is required
Automatic-Reboot-TimeWhen to reboot. "now" reboots immediately after the update

With this in place, the update run schedules a reboot at the end.

Example: a reboot is scheduled
kazulog@sv1:~$ sudo unattended-upgrade -v
Starting unattended upgrades script
/snip/
All upgrades installed
Found /var/run/reboot-required, rebooting
Shutdown msg: b"Reboot scheduled for Fri 2026-09-11 03:00:00 JST, use 'shutdown -c' to cancel."
A scheduled reboot can be cancelled with sudo shutdown -c. Setting Automatic-Reboot-Time inside working hours can take services down whenever an update lands, so choose a time when a restart is acceptable.

Excluding Packages from Automatic Updates

List packages you do not want updated in Package-Blacklist. The entries are regular expressions.

Excluding packages
Unattended-Upgrade::Package-Blacklist {
	"nginx";
	"^linux-";
};

Turning Automatic Updates Off

There are three ways, and they differ in scope.

MethodCommandEffect
Stop applying updates onlySet Unattended-Upgrade to "0" in 20auto-upgradesPackage lists are still refreshed. Recommended
Stop all periodic workSet both values to "0" in 20auto-upgradesThe equivalent of apt update stops as well
Stop the timer itselfsudo systemctl disable --now apt-daily-upgrade.timerThe timer no longer fires. Reinstalling the package may bring it back
Example: turning automatic updates off
kazulog@sv1:~$ printf 'APT::Periodic::Update-Package-Lists "0";\nAPT::Periodic::Unattended-Upgrade "0";\n' | sudo tee /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Unattended-Upgrade "0";
kazulog@sv1:~$ apt-config dump APT::Periodic::Unattended-Upgrade
APT::Periodic::Unattended-Upgrade "0";
kazulog@sv1:~$ sudo systemctl disable --now apt-daily-upgrade.timer
Removed '/etc/systemd/system/timers.target.wants/apt-daily-upgrade.timer'.
kazulog@sv1:~$ systemctl list-timers 'apt-daily*' --all --no-pager
NEXT                        LEFT LAST                        PASSED UNIT            ACTIVATES
Fri 2026-09-11 05:56:09 JST  13h Thu 2026-09-10 13:30:25 JST      - apt-daily.timer apt-daily.service

1 timers listed.
kazulog@sv1:~$

apt-daily-upgrade.timer no longer appears in list-timers. To restore it, run enable --now and set the values back to "1".

sudo dpkg-reconfigure --priority=low unattended-upgrades offers an interactive way to enable or disable the feature. It rewrites 20auto-upgrades.

Test Environment and Session Logs

The examples were captured on Ubuntu 26.04 LTS Server (unattended-upgrades 2.12ubuntu9) running on CML. The session log of each step can be downloaded below.

StepSession log
Initial state (settings, timers, scope)log
Previewing the updates (–dry-run)log
Which repository provides the candidateslog
Applying the updateslog
Reboot requirement and logslog
Adding -updates to the scopelog
Configuring and triggering the automatic rebootlog
Cancelling the scheduled rebootlog
Disabling and re-enabling automatic updateslog
Restoring the defaultslog

Reference

Ubuntu Server documentation: Automatic updates

Related articles

Ubuntu official pages