Check Files Against deb-md5sums with dpkg --verify
A package's deb-md5sums control file is the quiet record that lets you ask "has anything under this package actually changed since install". You will check installed files against those recorded digests, using the dpkg tools already on this machine, version 1.22.6ubuntu6.6. Allow about ten minutes for one package, longer if a failure sends you further. Every check here reads metadata and file contents; nothing gets reinstalled and no service state changes.
The route
Jump straight to the step you need, or tick off Done means at the end.
1. Understand what md5sums records
- One line per ordinary file. A 32-character hex MD5 digest, two spaces, then the file path, stored as
DEBIAN/md5sumsinside the binary package. - Paths are root-relative. A path like
usr/bin/dpkgis written in the package's own convention, so any check has to interpret it from the filesystem root. - Not a security boundary. MD5 proves nothing about authenticity and will not catch a deliberately crafted replacement. A matching sum only means the bytes match the recorded digest; package signatures and trusted repository metadata do the security job.
- Missing list, since dpkg 1.16.3. If a package ships without this file,
dpkgcan generate matching information on unpack. Treat an absent list as a metadata condition to look into, not a reason to hand-roll a new digest file.
2. Locate the installed list
Unprivileged, and changes nothing. Replace PACKAGE_NAME with something actually installed:
$ PACKAGE_NAME=dpkg
$ dpkg-query -W -f='${Status} ${Version}\n' "$PACKAGE_NAME"
install ok installed 1.22.6ubuntu6.6
$ list="/var/lib/dpkg/info/${PACKAGE_NAME}.md5sums"
$ test -r "$list" && printf 'readable: %s\n' "$list"
readable: /var/lib/dpkg/info/dpkg.md5sums
Your version number will differ. If the first command says the package is not installed, stop there. If the list itself is missing, do not read that as a clean result: run the package manager's own verification in the next step instead, and note that local metadata is incomplete.
Checkpoint
Look at a few records before you check them, without editing the file:
$ sed -n '1,5p' "$list"
1c9124caa101c66a71237b0285acd7ac usr/bin/dpkg
aed1ccb3ffb685897892e5e1b271da30 usr/bin/dpkg-deb
0668d2bbdce0e8a1fa9c74a77c5b0e6d usr/bin/dpkg-divert
95f8fc9fde6969241b103937676d9ac1 usr/bin/dpkg-maintscript-helper
1700704852357c42016f0b3d3721c12d usr/bin/dpkg-query
Those digests belong to this exact installed version. Do not copy them to another machine and call it a baseline.
3. Run the direct md5sum check
Run from /, because every record names a path relative to the installed filesystem tree:
$ cd /
$ md5sum -c --status /var/lib/dpkg/info/dpkg.md5sums
$ printf 'exit status: %s\n' "$?"
exit status: 0
With --status, success is silent and the exit status is 0. Non-zero means at least one record could not be verified. Drop --status to see each result individually:
$ cd /
$ md5sum -c /var/lib/dpkg/info/dpkg.md5sums
/usr/bin/dpkg: OK
/usr/bin/dpkg-deb: OK
...
The list can run long and the order just follows the file. What matters is OK, FAILED, and any missing-or-unreadable message, plus the exit status: a screen of OK lines does not override a non-zero exit.
Common trap: do not run this from your home directory. A record such as usr/bin/dpkg then resolves to ./usr/bin/dpkg, which produces missing-file errors that have nothing to do with the real /usr/bin/dpkg.
4. Use dpkg for the package-level result
dpkg --verify reads dpkg's own database and checks the named package, handling package selection for you, which usually makes it the clearer first check:
$ dpkg --verify dpkg
$ printf 'exit status: %s\n' "$?"
exit status: 0
A clean run prints nothing. Its output format is meant for paths that fail, so a missing line or a changed-file result deserves a look. The database only checks files it holds an MD5 record for, so a clean result does not prove every configuration or runtime-generated file is covered.
Drop the package name to check everything installed. This takes longer and can surface unrelated existing problems:
$ dpkg --verify
$ printf 'exit status: %s\n' "$?"
exit status: 0
Reach for the package-specific form first when you are chasing one application. Elevated privileges are not normally needed for these reads; if your account cannot see a package's files or the dpkg database, fix that access issue through local policy rather than reaching for sudo by reflex.
5. Classify a failure before you touch anything
A failed digest has several honest explanations: a deliberate admin change, a package upgrade interrupted between files and metadata, filesystem corruption, a missing file, or something unauthorised. Capture the path and package version first. Then compare against the package's real intended contents, from a trusted repository or the exact matching .deb. Do not overwrite the file just because the MD5 differs.
For a missing or changed executable, gather evidence before you repair anything:
$ dpkg-query -W -f='${Package} ${Version}\n' dpkg
dpkg 1.22.6ubuntu6.6
$ stat /usr/bin/dpkg
$ dpkg --verify dpkg
$ printf 'verify status: %s\n' "$?"
If the file is security-sensitive, preserve that output and follow your incident or change process. These checks cannot tell you who changed a file, when, or whether the recorded digest itself ever came from somewhere trustworthy.
6. Avoid destructive repair shortcuts
Destructive action
Do not delete a failing file, edit /var/lib/dpkg/info/*.md5sums, or regenerate a list purely to make the next check pass. Any of those can destroy evidence or hide the actual problem, and there is no undo for a deleted file or an overwritten baseline. Restore from a known-good package or backup only once the cause and change approval are settled.
If the package is genuinely damaged and repair is authorised, use your normal package-management procedure, then rerun dpkg --verify PACKAGE_NAME. Reinstalling changes state and can run maintainer scripts, so schedule it and keep a rollback plan for whatever service depends on it.
Done means
- Identified the installed package version and its md5sums metadata.
- Ran the direct check from
/, or useddpkg --verify. - Treated a silent success and exit status 0 as a clean result, not proof of authenticity.
- Recorded every missing or changed path before attempting repair.
- Left the baseline and any evidence untouched, and did not reinstall blindly.