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:
- The original version installed by the previous package (determined by the stored MD5 checksum).
- The current version residing on the filesystem.
- 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-oldso 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
diffbetween 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-confoldor--force-confnew.