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.
| Piece | Role |
|---|---|
The unattended-upgrades package | Applies the updates. It provides the unattended-upgrade command |
| systemd timers | Trigger 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".
dpkg -l unattended-upgrades
cat /etc/apt/apt.conf.d/20auto-upgradeskazulog@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:~$| Setting | Meaning |
|---|---|
APT::Periodic::Update-Package-Lists | 1 runs the equivalent of apt update daily |
APT::Periodic::Unattended-Upgrade | 1 applies updates daily |
apt-config dump shows the effective values across all configuration files.
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.
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.
systemctl list-timers 'apt-daily*'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.
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:~$| Setting | Meaning |
|---|---|
OnCalendar=*-*-* 6:00 | Runs daily at 06:00 |
RandomizedDelaySec=60m | Adds a random delay of up to 60 minutes (so that many servers do not hit the mirrors at once) |
Persistent=true | Runs 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.
grep -E 'distro_codename' /etc/apt/apt.conf.d/50unattended-upgradeskazulog@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.
sudo unattended-upgrade --dry-run -vkazulog@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.
sudo unattended-upgrade -vkazulog@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 installedChecking 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.
ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgskazulog@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/.
| File | Contents |
|---|---|
unattended-upgrades.log | The run itself (selected packages, start and finish) |
unattended-upgrades-dpkg.log | Detailed output from unpacking the packages |
unattended-upgrades-shutdown.log | Records of waiting for an upgrade during shutdown |
sudo tail /var/log/unattended-upgrades/unattended-upgrades.logkazulog@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.logChanging the Settings
Including Non-Security Updates
Uncomment the -updates line in 50unattended-upgrades.
sudo vi /etc/apt/apt.conf.d/50unattended-upgradesUnattended-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.
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-corea=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.
printf 'Unattended-Upgrade::Automatic-Reboot "true";\nUnattended-Upgrade::Automatic-Reboot-Time "03:00";\n' | sudo tee /etc/apt/apt.conf.d/51custom-reboot| Setting | Meaning |
|---|---|
Automatic-Reboot | true reboots when a reboot is required |
Automatic-Reboot-Time | When to reboot. "now" reboots immediately after the update |
With this in place, the update run schedules a reboot at the end.
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."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.
Unattended-Upgrade::Package-Blacklist {
"nginx";
"^linux-";
};Turning Automatic Updates Off
There are three ways, and they differ in scope.
| Method | Command | Effect |
|---|---|---|
| Stop applying updates only | Set Unattended-Upgrade to "0" in 20auto-upgrades | Package lists are still refreshed. Recommended |
| Stop all periodic work | Set both values to "0" in 20auto-upgrades | The equivalent of apt update stops as well |
| Stop the timer itself | sudo systemctl disable --now apt-daily-upgrade.timer | The timer no longer fires. Reinstalling the package may bring it back |
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.
| Step | Session log |
|---|---|
| Initial state (settings, timers, scope) | log |
| Previewing the updates (–dry-run) | log |
| Which repository provides the candidates | log |
| Applying the updates | log |
| Reboot requirement and logs | log |
| Adding -updates to the scope | log |
| Configuring and triggering the automatic reboot | log |
| Cancelling the scheduled reboot | log |
| Disabling and re-enabling automatic updates | log |
| Restoring the defaults | log |
Reference
Ubuntu Server documentation: Automatic updates
Related articles
- Changing the Hostname on Ubuntu 26.04 LTS Server
- Ubuntu 26.04 LTS Server System Optimization with apt update/upgrade
- Changing the Timezone to Japan Standard Time (JST) on Ubuntu 26.04 LTS Server
- Creating Users and Granting sudo Privileges on Ubuntu 26.04 LTS Server
- Configuring the SSH Server on Ubuntu 26.04 LTS Server
- Managing Services with systemctl and Reading Logs with journalctl on Ubuntu 26.04 LTS Server
- Configuring Automatic Updates on Ubuntu 26.04 LTS Server (unattended-upgrades)
- How to Install the Latest neovim from the Official Site on Ubuntu 26.04 LTS Server
- Configuring the Network on Ubuntu 26.04 LTS Server