Interrupted Package Transactions and Recovery

Updated

October 31, 2026

An interrupted update may leave a package unpacked but not configured, a service stopped, or an application with data already migrated. Repair begins by preserving evidence and identifying the failed stage. Package database consistency is a necessary check, not a complete application rollback.

Establish the failure boundary

If another package process is working, let it finish; identify it and the associated service instead of deleting lock files. Check space on both the filesystem holding /var and any separate /boot. Capture the failing command, the error, package status, recent APT and dpkg logs, source configuration and any relevant service logs before retrying:

sudo dpkg --audit
sudo tail -n 100 /var/log/dpkg.log
sudo tail -n 100 /var/log/apt/term.log
df -h / /var /boot
systemctl list-jobs

Logs may be absent or rotated; protect them if they contain sensitive information. Inspect the specific package using dpkg-query -l PACKAGE and apt-cache policy PACKAGE, replacing PACKAGE with the actual name. The dpkg manual explains package states and configuration. A failed network download, a full filesystem, a dependency conflict and a maintainer-script failure require different repairs.

Fix the identified cause first. For a reviewed, interrupted configuration, sudo dpkg --configure PACKAGE can retry that package’s configuration; sudo dpkg --configure -a may configure all pending packages and run their scripts. sudo apt-get -s -f install previews APT’s proposal to fix broken dependencies. The actual apt-get -f install can change or remove packages and run scripts, so review its full proposal and stop if it is unexpected. Neither command repairs the underlying storage fault or makes an unsafe script safe. Do not use force options or edit package database files as a routine fix.

Lab: recover a deliberately failed configuration

Use the disposable bl05-packages-lab clone, not a production host. Keep bl02 off, confirm the clone in the VM manager and have its console and a tested recovery copy available. This exercise creates and installs a tiny package whose post-install script intentionally fails until a marker exists. It will modify the clone’s package database and /run. dpkg-deb and dpkg must be present.

First ensure sudo dpkg --audit is empty, no package operation is running, bl05-recovery-demo has no existing installed or residual record, and /run/bl05-recovery-ready does not exist. If any condition fails, stop and investigate instead of overwriting another owner’s state:

sudo dpkg --audit
dpkg-query -l bl05-recovery-demo
ls -l /run/bl05-recovery-ready

The last two queries are expected to report no match. A package in rc or any other recorded state is not a clean baseline. Build the known lab package as the unprivileged user:

labdir=$(mktemp -d)
printf 'Lab directory: %s\n' "$labdir"
mkdir -p "$labdir/pkg/DEBIAN" "$labdir/pkg/usr/share/bl05-recovery-demo"
cat > "$labdir/pkg/DEBIAN/control" <<'CONTROL'
Package: bl05-recovery-demo
Version: 1.0-1
Architecture: all
Maintainer: Lab Operator <lab@example.invalid>
Description: Disposable package recovery exercise
 A deliberately failing post-install script for a lab clone.
CONTROL
cat > "$labdir/pkg/DEBIAN/postinst" <<'SCRIPT'
#!/bin/sh
set -e
if [ "$1" = configure ] && [ ! -f /run/bl05-recovery-ready ]; then
    echo 'Lab prerequisite is missing' >&2
    exit 1
fi
SCRIPT
chmod 755 "$labdir/pkg/DEBIAN/postinst"
printf 'Recovery exercise\n' > "$labdir/pkg/usr/share/bl05-recovery-demo/readme"
dpkg-deb --root-owner-group --build "$labdir/pkg" "$labdir/demo.deb"
dpkg-deb --info "$labdir/demo.deb"
dpkg-deb --contents "$labdir/demo.deb"

Review the package and script above before installing: package scripts execute as root. If the build failed or the contents differ, stop. The next command intentionally returns an error and leaves this package in an incomplete state:

sudo dpkg -i "$labdir/demo.deb"
sudo dpkg --audit
dpkg-query -l bl05-recovery-demo

Confirm the failure mentions the lab prerequisite and the audit names the lab package. If anything else failed, stop and investigate. Supply the deliberately missing prerequisite, then retry only this package:

sudo touch /run/bl05-recovery-ready
sudo dpkg --configure bl05-recovery-demo
dpkg-query -l bl05-recovery-demo
sudo dpkg --audit

A successful retry should show the package fully installed and no audit issues. If it does not, preserve the output and do not continue to cleanup until the cause is understood. Remove only the lab package and marker, then inspect the result:

sudo dpkg -r bl05-recovery-demo
sudo rm -- /run/bl05-recovery-ready
sudo dpkg --audit
dpkg-query -l bl05-recovery-demo
printf 'Remove this disposable directory only after checking: %s\n' "$labdir"

Remove the printed temporary build directory after confirming it is the one created for this exercise. If the shell session is lost, recover the recorded path; do not guess. Power off the clone before starting bl02.

Rollback has boundaries

Removing or downgrading a package does not necessarily reverse database migrations, external side effects, generated files or a changed configuration. An older package may not be available or compatible with newer data. Recovery may require a coordinated restore of software, configuration and application data from a tested, consistent backup; a same-host VM clone is not an independent backup. Verify both package state and the application through a client after recovery.

Practice and recall

Record the intentional error, status before and after configuration, the exact prerequisite and final audit. Explain why the targeted retry was appropriate here and why it must not be generalized into running arbitrary maintainer scripts by hand. Compare the package-state repair with an application-data restore.