Repair and Verify the kmod Module Dependency Database

You will identify the module database used by modprobe, check whether it is current, and regenerate it safely with depmod when needed. On this machine the installed tools are kmod 31, and the running kernel is 6.8.0-139-generic.

Allow about ten minutes. You need a shell for the inspection steps. Regenerating the database writes under /lib/modules, so that part needs elevated privileges. This guide does not install a module, load one into the kernel, or edit a configuration file.

1. Locate the database for the running kernel

kmod keeps one module directory per kernel version. The active version comes from uname -r, not from whichever directory happens to sort last:

$ kernel=$(uname -r)
$ printf 'kernel: %s\n' "$kernel"
$ ls -l "/lib/modules/$kernel/modules.dep" "/lib/modules/$kernel/modules.dep.bin"

Both files should normally exist. modules.dep is the readable text counterpart. modules.dep.bin is the binary hashed form that kmod tools and libkmod use. The binary file is not a replacement that you should decode by hand, and the text file is not the input that modprobe reads.

Checkpoint: If either path is missing, copy the exact error and kernel version before doing anything else. A missing directory can mean that the matching kernel modules are not installed at all, rather than a damaged database.

2. Check the installed kmod version

Use the same package family for depmod and modprobe. Their on-disk database format is an implementation detail, so a parser or utility written for another release is a poor repair tool.

$ depmod --version
kmod version 31
+ZSTD +XZ -ZLIB +LIBCRYPTO -EXPERIMENTAL

Your feature line may differ. The relevant check is that the command runs and reports the kmod version supplied by the operating system. This guide describes the kmod 31 behaviour installed here, while the file format remains subject to change.

3. Test regeneration without changing files

depmod scans modules for one selected kernel and normally writes dependency and map files into that kernel's module directory. Its --dry-run or --show mode sends the generated content to standard output instead. Redirect that output to a temporary file if you want to inspect it without flooding the terminal:

$ kernel=$(uname -r)
$ depmod --dry-run "$kernel" > /tmp/depmod-$kernel.txt
$ test -s "/tmp/depmod-$kernel.txt" && echo "dry run produced output"
dry run produced output

The temporary file is only a diagnostic copy. It is not a replacement for modules.dep.bin, and moving it into /lib/modules would be wrong because the dry-run stream contains the generated text and map output, not a ready-made binary database.

Do not add a module filename to this command as a shortcut. When filenames are supplied, depmod examines only those modules, which is rarely useful unless the complete relevant set is supplied. A partial scan can leave dependency information incomplete.

4. Regenerate the complete database

Only do this after confirming the target kernel directory is the one you mean. The write is normally harmless and reversible by running the same command again, but it can affect subsequent module loading if the underlying module tree is incomplete or inconsistent.

$ kernel=$(uname -r)
$ sudo depmod "$kernel"

No output is expected on a successful normal run. The command creates or refreshes modules.dep and modules.dep.bin, along with other kmod metadata such as symbol maps. It does not load a module into the running kernel.

Checkpoint: If the command reports an error, stop and keep the output. Do not delete the existing database to make the error disappear. Check that /lib/modules/$kernel contains the modules for that kernel, that the filesystem is writable, and that the module files came from a matching kernel package.

5. Verify what modprobe can resolve

Use modinfo for a future-proof view of a module rather than reading either dependency file. Pick a module name that exists on the host. This example uses irqbypass, which is present as a loadable module on this machine:

$ modinfo -F filename irqbypass
/lib/modules/6.8.0-139-generic/kernel/virt/lib/irqbypass.ko.zst

If that name is absent, list a known module file under the selected directory and pass its full path to modinfo:

$ find "/lib/modules/$kernel" -type f -name '*.ko*' -print -quit
$ modinfo -F depends /path/from-the-command-above

The first command prints the module's installed filename. The second prints its declared module dependencies, when any exist. This checks the installed module metadata without depending on the private layout of modules.dep.bin.

To inspect the load plan without changing kernel state, use modprobe --dry-run --verbose with a real module name:

$ modprobe --dry-run --verbose loop

Dry-run output varies with the host and its modprobe configuration. It may be empty when no insertion command is needed or when the module is already present. The important boundary is that --dry-run does not insert or remove modules.

6. Avoid the common traps

If you need to undo a repair, there is no hand-edit to reverse. Re-run sudo depmod <the exact kernel version> after restoring the correct module package and its files. The generated files will then be rebuilt from that module tree.

Done means