Rebuild Linux Module Dependencies Safely with depmod
You installed a driver, and modprobe cannot find it or its dependencies. Rebuilding the index with depmod usually fixes that. This guide rebuilds the dependency and symbol indexes for one installed kernel, verifies what changed, and covers staging trees and configuration files. The examples match kmod 31 and take about 10 minutes if the module tree is healthy.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell account, the target kernel's module directory, and sudo for the final write.
Before you start
depmod reads kernel modules from /lib/modules/VERSION by default, where VERSION is the running kernel from uname -r. With no file names, it probes all modules. It does not load or unload a module; it creates metadata used later by tools such as modprobe.
Check the executable and the target directory first:
$ depmod --version
kmod version 31
$ KVER=$(uname -r)
$ printf 'kernel: %s\n' "$KVER"
kernel: 6.8.0-139-generic
$ test -d "/lib/modules/$KVER" && echo 'module tree exists'
module tree exists
Your kernel version will differ. If the directory is missing, stop here. Installing or copying modules is a separate job, and running depmod cannot create a useful index for files that are not present.
1. Preview the dependency data
Use the dry-run form before changing a live tree. The -n option sends the generated dependency and map data to standard output instead of writing the module directory. Limit the display while investigating, because a complete index can be large:
$ KVER=$(uname -r)
$ depmod -n "$KVER" | sed -n '1,8p'
kernel/arch/x86/events/amd/amd-uncore.ko.zst:
kernel/arch/x86/events/intel/intel-cstate.ko.zst:
kernel/arch/x86/events/rapl/rapl.ko.zst:
kernel/arch/x86/kernel/cpu/mce/mce-inject.ko.zst:
kernel/arch/x86/kernel/msr.ko.zst:
kernel/arch/x86/kernel/cpuid.ko.zst:
kernel/arch/x86/crypto/twofish-x86_64.ko.zst: kernel/crypto/twofish_common.ko.zst
Checkpoint
Each line names a module followed by the modules it needs. A line ending at the colon has no recorded dependency. The exact list depends on your kernel package, compression format and installed drivers, so compare structure rather than copying these names.
2. Rebuild the live index
When the preview is sensible, rebuild the index for the chosen kernel:
$ sudo depmod "$KVER"
$ printf 'depmod exit status: %s\n' "$?"
depmod exit status: 0
This writes files such as modules.dep, modules.dep.bin, modules.symbols, modules.symbols.bin and, when applicable, modules.devname under /lib/modules/$KVER. The binary index is the one kmod tools use. The text file is for human reading only, and its format is not a stable interface.
Warning
This is a state-changing command. It does not insert a module or restart a service, but it can still affect the next module load, so run it during a maintenance window if you are repairing a driver on a production host.
Recovery
Restore the index files from your package or system backup, then run the package's normal module post-install step. Do not hand-edit modules.dep.
3. Make repeated rebuilds cheap
The -A or --quick option checks whether any module is newer than modules.dep. If nothing is newer, it exits silently without regenerating the files:
$ sudo depmod --quick "$KVER"
$ printf 'quick check status: %s\n' "$?"
quick check status: 0
Tip
Silence means that no rebuild was needed, not that the directory was inspected successfully in every way. Use the ordinary command when you have replaced indexes, changed depmod configuration, or want an unambiguous regeneration.
4. Use a staging tree without contaminating the host
Distribution and image builders can generate metadata before the files are installed. With -b, depmod prepends a staging root to the normal module path and strips that root from paths recorded in the result. The expected layout is:
$ STAGE=/path/to/staging-root
$ KVER=TARGET_KERNEL_VERSION
$ find "$STAGE/lib/modules/$KVER" -maxdepth 1 -type d -print
/path/to/staging-root/lib/modules/TARGET_KERNEL_VERSION
$ depmod -b "$STAGE" -n "$KVER" | sed -n '1,5p'
Replace both placeholders with a real build directory and kernel version. The dry run keeps this example non-destructive. To write the staged index, remove -n after checking the input tree.
Tip
If the image uses a different module prefix, kmod 31 also supports -m, and -o selects a separate output root. Read the interaction carefully before combining these options: output precedence can make the input and output trees differ.
5. Control which duplicate module wins
Files in /lib/depmod.d, /usr/lib/depmod.d, /usr/local/lib/depmod.d, /run/depmod.d and /etc/depmod.d can alter processing order. Files are read as simple commands, with blank lines and comments ignored. A trailing backslash continues a line.
For example, a configuration file can give an external module directory priority:
# /etc/depmod.d/90-local-modules.conf
external * /opt/vendor/lib/modules
search external updates built-in
searchlists directory classes from highest to lowest priority. The built-in default already givesupdatespriority overbuilt-in.overrideis narrower:override MODULENAME KERNELVERSION SUBDIRECTORYselects a matching module from a named subdirectory, and*can match every kernel version.
Configuration changes do nothing until you regenerate the relevant index. Preview with depmod -n, then rebuild. If you need a one-off configuration location, -C FILE_OR_DIRECTORY replaces the default configuration lookup. Keep locally managed files separate from package-owned files so an upgrade does not erase your decision.
6. Diagnose unresolved symbols
Missing symbols usually point to a module built for the wrong kernel, an incomplete install, or a third-party driver that was not built against the matching kernel. The -e check reports unresolved symbols only when paired with either -F System.map or -E Module.symvers. Those options are mutually exclusive:
$ sudo depmod -e -F /path/to/System.map "$KVER"
$ printf 'symbol check status: %s\n' "$?"
symbol check status: 0
Use the System.map produced for the same kernel build. Use -E instead when you have that build's Module.symvers.
Warning
A non-zero result or an unresolved-symbol line is a diagnostic signal, not a reason to force the module into the kernel. Check the module's build logs and kernel version first.
Common traps
- No version means the running kernel. Running
depmodwith no version targets it. Pass an explicit version when preparing another kernel. - Filenames narrow the scan. Passing them restricts the scan to those modules, which is rarely correct unless you have supplied the complete set.
modules.depis not an editing format. Usemodinfofor stable module information and rerun depmod after changing the module tree.-vis noisy. It reports symbols and providers and can produce a great deal of output. Use it for a focused investigation, not as a routine health check.- Exit 0 is not load success. A successful exit status confirms depmod completed its work. It does not prove that an unsigned, incompatible or policy-blocked driver will load.
Done means
- Versions confirmed. You checked kmod and the target kernel version.
- Preview seen. You looked at the generated dependency data with
depmod -n. - Right kernel rebuilt. You rebuilt the intended kernel's indexes, with
sudoonly for the write. - Binary index is the truth.
modules.dep.bin, not hand-edited text, is the operational index. - Modes separated. You can tell live-tree repairs, staging builds and depmod.d priority rules apart.
- Matching symbol files. You used them before treating unresolved symbols as a build problem.