Home / Alt manpages / unattended-upgrade(8)

  • unattended-upgrade(8)
  • Admin command
  • linux

Safely Test and Run unattended-upgrade on Ubuntu

Run unattended-upgrade the wrong way and you find out mid-deploy that a package restarted a service you needed. This guide inspects the APT policy, simulates the upgrades it would select, then runs them deliberately once the result looks acceptable, plus what to check when a package is held back or an upgrade gets interrupted.

Allow about fifteen minutes for inspection and a dry run. The real upgrade can take longer, and can restart services or require a reboot. This guide uses the Ubuntu package version 2.9.1+nmu4ubuntu1 installed on the reference system: check your own version, since command output and configuration options can differ.

You need an Ubuntu or Debian-family system using APT, a shell, and sudo access. The installation step needs elevated privileges; reading configuration and logs normally does not.

1. Confirm the command and package

Start with read-only checks. This command has no useful --version option, so query the package instead:

$ command -v unattended-upgrade
/usr/bin/unattended-upgrade
$ dpkg-query -W -f='${Package} ${Version}\n' unattended-upgrades
unattended-upgrades 2.9.1+nmu4ubuntu1
$ unattended-upgrade --help

The help text is the installed command's contract. In this version, --dry-run is described as a simulation that can download packages but does not install them. That is less destructive than a real run, but it can still burn network bandwidth and local package-cache space.

Checkpoint

If command -v finds a different binary, or the package query fails, stop and identify which package actually supplied your command before copying the examples below.

2. Inspect what APT is allowed to install

unattended-upgrade is the backend for the APT setting APT::Periodic::Unattended-Upgrade. Its default configuration file is /etc/apt/apt.conf.d/50unattended-upgrades. Read it without editing:

$ sed -n '1,180p' /etc/apt/apt.conf.d/50unattended-upgrades
$ apt-config dump | grep -E 'APT::Periodic::(Update-Package-Lists|Unattended-Upgrade)'

Look first at Unattended-Upgrade::Allowed-Origins. The usual Ubuntu file permits the release and security origins while leaving updates, proposed and backports commented out, but your file may differ. A package is not automatically approved just because an update exists in an APT repository.

Do not assume a comment in 50unattended-upgrades is the effective value. A later file in /etc/apt/apt.conf.d/ can add or override settings, and apt-config dump shows the merged configuration APT will actually use.

3. Simulate the upgrade

Run the simulation with debugging and verbose output so the decision lands in the normal log. This is an elevated command because it touches APT and its package state:

$ sudo unattended-upgrade --dry-run --debug --verbose

Do not treat a quiet terminal as proof nothing happened. The manpage names these log files:

$ sudo tail -n 80 /var/log/unattended-upgrades/unattended-upgrades.log
$ sudo tail -n 80 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log

On this installed release, the help output says the dry run may download packages but will not install them. Review the package names, origins and any held-back packages in the log. If the output mentions a lock, another APT process is active: wait for it to finish, do not delete lock files.

Checkpoint

Continue only if the selected origins are what you expect, the package list looks reasonable, and there is no unresolved dpkg error. A dry run does not guarantee a later installation succeeds, because repository metadata and dependencies can change in between.

4. Run approved updates

Warning

This step changes the installed system. Packages can replace libraries, restart services, change configuration files, or leave a reboot required. Take a current backup and arrange a maintenance window on a production host.

Once the simulation looks acceptable, run the same command without --dry-run:

$ sudo unattended-upgrade --verbose

The command returns control once its selected work completes. Verify the exit status immediately:

$ printf 'exit status: %s\n' "$?"
exit status: 0

Status zero means the command completed successfully, not that every available package got upgraded. Packages can stay back because they are outside the allowed origins, blacklisted, held, or simply not installable right now.

Do not add --no-minimal-upgrade-steps casually. Minimal upgrade steps are the default here, splitting work into smaller, interruptible sets. The alternative tries to upgrade everything together, which is less convenient to interrupt.

5. Check the scheduler rather than starting a second job

The normal unattended path is usually driven by apt-daily-upgrade.service, started by apt-daily-upgrade.timer, or by a cron job. Inspect the unit and timer as an ordinary user:

$ systemctl cat apt-daily-upgrade.service apt-daily-upgrade.timer
$ systemctl list-timers apt-daily-upgrade.timer
$ systemctl is-enabled apt-daily-upgrade.timer

On systems using the systemd unit, the service invokes /usr/lib/apt/apt.systemd.daily install. The timer's schedule can include a random delay, so the displayed time is not necessarily the exact start time. If a scheduled run is already active, do not launch a manual run alongside it.

If the timer is absent or disabled, check /etc/cron.daily/apt and the APT periodic values instead. Enabling a scheduler is a policy change and sits outside this runbook: record the existing state before touching it, and follow your distribution's documented enablement method.

6. Recover from an interrupted run

If a run stops with a dpkg error, do not repeatedly retry unattended upgrades. Capture the relevant output first:

$ sudo tail -n 120 /var/log/unattended-upgrades/unattended-upgrades.log
$ sudo tail -n 120 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
$ dpkg --audit

Resolve the specific package or repository problem through your normal change process. After an interrupted dpkg operation, the installed configuration supports an automatic repair setting named Unattended-Upgrade::AutoFixInterruptedDpkg, enabled by default in the shipped file. Do not enable extra recovery behaviour blindly: inspect the package manager error first and confirm what the repair will actually do.

Once the underlying problem is fixed, start again with a dry run. If it reports a dpkg configuration error, follow the named package's repair instructions before attempting installation again. If the host runs a critical service, check its status and application health once packages go in.

Done means

  • Confirmed the command and package. You know exactly which binary and version you are running.
  • Inspected the merged config. You checked the allowed origins as APT will actually apply them.
  • Reviewed a dry run. It completed and you read its logs before doing anything real.
  • Approved the real run. It only touched packages after the simulation looked right.
  • Checked the scheduler. You confirmed no concurrent APT job was going to collide with yours.
  • Verified a clean finish. The final logs and dpkg --audit show no unresolved package error.