Debian Conffiles and Handling Dpkg File Clashes

This article explains the concept of conffiles in the Debian operating system and details how the dpkg package manager handles conflicts between local administrative edits and upstream configuration changes during system updates.

What is a Conffile?

In Debian and Debian-derived distributions (such as Ubuntu), a conffile is a configuration file tracked directly by the dpkg package management system. When a package maintainer builds a Debian package (.deb), they declare which files inside /etc are configuration files by listing them in the package's internal DEBIAN/conffiles metadata.

The primary purpose of a conffile is to preserve custom user settings across package upgrades. When a package is first installed, dpkg records an MD5 checksum of each conffile in its status database located at /var/lib/dpkg/status. This recorded hash serves as a reference point to determine whether a configuration file has been modified locally by the system administrator or an automated script.

Regular files in a package are automatically overwritten during an upgrade. Conffiles, by contrast, receive special handling to prevent the accidental loss of customized system behaviors.

How dpkg Detects a Configuration Clash

During a package upgrade, dpkg compares three distinct states of the file:

  1. The original version installed by the previous package (determined by the stored MD5 checksum).
  2. The current version residing on the filesystem.
  3. The new version provided by the incoming package update.

A conflict occurs only when both sides have changed: the local administrator has modified the existing file, and the upstream maintainer has updated the file in the new package version. If only the package maintainer updated the file (and the user never touched it), dpkg updates it silently. If only the user touched the file, dpkg leaves the user's version in place.

The Interactive dpkg Prompt

When a genuine clash is detected, dpkg pauses the installation process and displays an interactive prompt in the terminal:

Configuration file '/etc/example/example.conf'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** example.conf (Y/I/N/O/D/Z) [default=N] ?

The available actions function as follows:

  • Y or I (Install): Overwrites the local configuration file with the new version provided by the package maintainer. The existing local version is renamed with the extension .dpkg-old so changes can be recovered later.
  • N or O (Keep / Old): Retains the currently installed local configuration file, rejecting the maintainer's update. The new version from the package is saved alongside it with the extension .dpkg-dist.
  • D (Diff): Displays a unified diff between the local file and the incoming file directly in the terminal, allowing the administrator to inspect what changed before deciding.
  • Z (Shell): Spawns a background shell instance in the target directory. This allows the administrator to manually merge lines, check other logs, or make backups before exiting the subshell (using exit) to return to the prompt.

Automated and Non-Interactive Resolution

In automated environments where interactive prompts halt execution, dpkg provides force options that can be passed via command-line flags or APT configuration files (such as /etc/apt/apt.conf.d/):

  • --force-confold: Automatically keeps the existing configuration and places the new file in .dpkg-dist.
  • --force-confnew: Automatically installs the new version and backs up the modified file to .dpkg-old.
  • --force-confdef: Uses the default action (preferring the maintainer's version if unmodified locally, or keeping the local version if modified), prompting only if a decision cannot be deduced safely unless combined with --force-confold or --force-confnew.