Refresh the Dynamic Linker Cache Safely with ldconfig

Install a new shared library and the program that needs it still fails to find it: that is the moment most people meet ldconfig for the first time. This guide covers inspecting the dynamic linker cache, refreshing it after installing shared libraries, and test-scanning a library directory without touching the host. The examples match ldconfig from glibc 2.39, installed here as libc-bin 2.39-0ubuntu8.9. Allow about ten minutes. A normal refresh needs root; inspection does not.

1. Confirm the installed command and version

Start by checking which executable your shell will run and which implementation it reports:

$ command -v ldconfig
/usr/sbin/ldconfig
$ ldconfig --version
ldconfig (Ubuntu GLIBC 2.39-0ubuntu8.9) 2.39

The exact copyright and build details can differ. What matters is that the command is present and its version is known. The installed manual page comes from Linux man-pages 6.7 and documents the behaviour used here.

Checkpoint: if command -v finds a wrapper or a non-system copy, stop and inspect it before trusting examples that go on to change the cache.

2. Inspect the current cache without changing it

ldconfig -p prints the libraries recorded in the current cache. It does not rebuild that cache:

$ ldconfig -p | head -n 6
1116 libs found in cache `/etc/ld.so.cache'
        libz3.so.4 (libc6,x86-64) => /lib/x86_64-linux-gnu/libz3.so.4
        libz3.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libz3.so
        libzvbi.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzvbi.so.0
        libzvbi-chains.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzvbi-chains.so.0

Your count and first entries will differ as packages change. Search for one library by its SONAME or unversioned linker name:

$ ldconfig -p | grep -F -- 'libzstd.so'
        libzstd.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzstd.so.1
        libzstd.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libzstd.so

No result just means that name is not in the cache. It does not prove the file does not exist: the directory might not be configured, the cache might be stale, or the file might not have a name ldconfig recognises as a shared object.

3. Understand what ldconfig scans

When rebuilding, ldconfig scans directories from /etc/ld.so.conf, the trusted library directories, and anything supplied on the command line. On a 64-bit system, multi-architecture library paths matter, so do not assume /lib and /lib64 mean the same thing.

4. Test a directory without rebuilding the host cache

Before touching a production library directory, ask ldconfig to scan only that directory, skip the cache output, and skip link updates:

$ sudo ldconfig -nNXv /path/to/library-directory
/path/to/library-directory: (from <cmdline>:0)

The directory has to be readable, and root may be needed if permissions block access. An empty directory printing just its own heading is expected, not an error.

This is a diagnostic, not proof that a library is ABI-compatible with every consumer. Check the actual files separately:

$ find /path/to/library-directory -maxdepth 1 -type f -name 'lib*.so*' -printf '%f\n' | sort
$ readelf -d /path/to/library-directory/libexample.so.1.12 | grep -E 'SONAME|NEEDED'

Only run readelf against a file you trust. An unexpected library directory is a supply-chain and runtime security issue, not merely a cache problem.

5. Refresh the system cache after a library change

Only do this after installing, removing or replacing a shared library through your normal package or deployment process. First check the configuration files that define the search paths:

$ sed -n '1,160p' /etc/ld.so.conf
$ find /etc/ld.so.conf.d -maxdepth 1 -type f -name '*.conf' -print -exec sed -n '1,80p' {} \;

Review those paths for anything unexpected, then rebuild the cache as root:

$ sudo ldconfig
$ ldconfig -p | grep -F -- 'libexample.so'

A successful sudo ldconfig normally produces no output at all. Verify the result with ldconfig -p, then start or test the application that needs the library. If the command fails, keep the error output and resist the urge to rerun it with broader permissions.

Warning: a cache refresh changes /etc/ld.so.cache and may update links in configured library directories. It does not undo a bad library install. If the new library is wrong, use the package manager or deployment rollback that installed it, restore the previous configuration entry, and run sudo ldconfig again. Do not delete the cache as a first response.

6. Separate cache problems from loader problems

The cache is only one input to runtime linking. A program can still fail because its required SONAME is absent, its architecture is wrong, a dependency is missing, or the process is using a different loader path. Inspect the program's declared dependencies without executing it:

$ readelf -d /path/to/program | grep -E 'NEEDED|RPATH|RUNPATH'
$ file /path/to/program /path/to/library-directory/libexample.so.1.12

Compare each NEEDED name against ldconfig -p and the configured directories. Do not "fix" an unresolved dependency by copying a random library into /usr/lib or adding an untrusted directory globally: that can redirect many unrelated programs and turn into a security boundary failure.

Need a temporary per-process search path for a controlled test? Use the application's documented launch mechanism and record it. A global /etc/ld.so.conf.d entry is a persistent system change, so review it, back it up, and schedule its removal if it was only ever meant for a migration.

Done means