Set and Check dpkg File Ownership Overrides Safely
You will finish with a recorded dpkg override for a file, a way to inspect it, and the matching command to remove it. The examples first use a disposable dpkg administration directory, so you can learn the workflow without editing the host's package database. The installed command here is from dpkg 1.22.6ubuntu6.6, reported by package metadata on 23 September 2026.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell and the dpkg package. Reading and listing are ordinary commands. Changing the real override database normally needs sudo, and changing a real file immediately with --update can alter ownership and permissions, so take a backup or record the original state first.
1. Check the installed command
Confirm which command will run and read its version. These are read-only checks:
$ command -v dpkg-statoverride
/usr/bin/dpkg-statoverride
$ dpkg-query -W -f='${Package} ${Version}\n' dpkg
dpkg 1.22.6ubuntu6.6
$ dpkg-statoverride --version
Debian dpkg-statoverride version 1.22.6 (amd64)
The command manages a list of overrides. When a package installs a matching path, dpkg can use the listed user, group and mode instead of the package's normal metadata. This is persistent package configuration, not a one-off chmod.
2. Create an isolated test database
Use a temporary directory for practice. This command creates a sample file and a private dpkg administration directory. It does not touch /var/lib/dpkg:
$ test_root=$(mktemp -d /tmp/dpkg-statoverride-guide.XXXXXX)
$ mkdir -p "$test_root/var/lib/dpkg" "$test_root/rootfs/etc"
$ printf '%s\n' 'sample configuration' > "$test_root/rootfs/etc/example.conf"
$ chmod 0644 "$test_root/rootfs/etc/example.conf"
$ stat -c '%U %G %a %n' "$test_root/rootfs/etc/example.conf"
andy dixon 644 /tmp/dpkg-statoverride-guide.XXXXXX/rootfs/etc/example.conf
The final path includes a random directory name, so your output will differ. Keep the test_root variable in the same shell for the remaining examples. The temporary files are disposable, but leave them alone until you have finished checking the result.
3. Add an override without changing the file yet
--add stores four values: user, group, octal mode and path. The path does not need to exist. Use your current user and group for a harmless test, rather than guessing a privileged account:
$ test_user=$(id -un)
$ test_group=$(id -gn)
$ dpkg-statoverride --admindir "$test_root/var/lib/dpkg" \
--add "$test_user" "$test_group" 0600 "$test_root/rootfs/etc/example.conf"
$ dpkg-statoverride --admindir "$test_root/var/lib/dpkg" --list
andy dixon 600 /tmp/dpkg-statoverride-guide.XXXXXX/rootfs/etc/example.conf
The displayed line is the stored policy, not proof that the file was already changed. Notice that the mode is written in octal, so 0600 means owner read and write only. A common trap is to omit the leading zero or to read the output as a request rather than a record.
Checkpoint
If --list prints the path and returns status 0, the override is in the isolated database. A list with no matches returns status 1, which is useful for scripts and is not the same as a fatal command error.
4. Apply an override immediately when required
Use --update with --add when the existing path should be changed now as well as recorded. Because step 3 already created an entry, include the narrow overwrite force option too. This example uses the current account, so it can run without sudo:
$ dpkg-statoverride --admindir "$test_root/var/lib/dpkg" \
--force-statoverride-add --add --update "$test_user" "$test_group" 0600 \
"$test_root/rootfs/etc/example.conf"
$ stat -c '%U %G %a %n' "$test_root/rootfs/etc/example.conf"
andy dixon 600 /tmp/dpkg-statoverride-guide.XXXXXX/rootfs/etc/example.conf
On a real system, use a maintenance window if the file belongs to a service. For a root-owned or system path, the equivalent normally starts with sudo. A failed ownership change is an error to investigate, not a reason to assume that the recorded override was applied.
Do not use --update casually on a setuid program, an executable, a device or a service configuration. Removing an execute bit can stop a service; adding access can weaken its boundary. If you need a reversible change, record the original output from stat and the current override from --list before proceeding.
5. Find, replace and remove entries
List everything, or restrict the output with a glob pattern. Quote the pattern so the shell does not expand it first:
$ dpkg-statoverride --admindir "$test_root/var/lib/dpkg" \
--list '/tmp/*/rootfs/etc/*'
andy dixon 600 /tmp/dpkg-statoverride-guide.XXXXXX/rootfs/etc/example.conf
Adding a second entry for the same path is refused by default. To replace an existing entry, use the specific force option documented for this action:
$ dpkg-statoverride --admindir "$test_root/var/lib/dpkg" \
--force-statoverride-add --add "$test_user" "$test_group" 0640 \
"$test_root/rootfs/etc/example.conf"
$ dpkg-statoverride --admindir "$test_root/var/lib/dpkg" --list
andy dixon 640 /tmp/dpkg-statoverride-guide.XXXXXX/rootfs/etc/example.conf
Force options are expert territory. The narrow option above replaces the database entry, but it does not by itself change the existing file's mode. If you also need the file changed, use --update deliberately and verify with stat.
To undo the persistent override, remove the path from the list:
$ dpkg-statoverride --admindir "$test_root/var/lib/dpkg" \
--remove "$test_root/rootfs/etc/example.conf"
$ dpkg-statoverride --admindir "$test_root/var/lib/dpkg" --list
$ printf 'list status: %s\n' "$?"
list status: 1
--remove leaves the file's current ownership and mode unchanged. That is deliberate: if an earlier --update changed the file, removing the override does not restore the old mode. Restore it separately from your recorded stat result if that is what you intend.
6. Repeat the workflow on the real host
When you are ready, inspect the live database before changing it:
$ sudo dpkg-statoverride --list
$ sudo dpkg-statoverride --list '/usr/lib/*'
Use the exact path returned by the list command. For a new package-time rule, add it with a named account or a numeric account such as #0, and an explicitly octal mode:
$ sudo dpkg-statoverride --add root servicegroup 0750 /path/to/program
Replace every placeholder with an account, group and path that exist in your deployment. A rule can be stored for a path that is not present yet, which is useful before a package is installed. It also means a typo can sit unnoticed until a later package operation, so list the result immediately.
The default administration directory is /var/lib/dpkg. For testing another database, use --admindir; --root and --instdir also affect where dpkg considers the installation root, but they are not interchangeable with a random path prefix. Avoid setting DPKG_ROOT or DPKG_ADMINDIR in a shell profile unless you want that alternate context for every dpkg command in the session.
Done means
- You checked the installed dpkg-statoverride version and option syntax.
- You can list the live override before changing it.
- Your new user, group, octal mode and exact path are recorded.
- You know whether you used
--update, and verified any immediate change withstat. - You can replace an entry with the narrow force option when necessary.
- You know that
--removeremoves policy but does not restore file metadata.