The library is gone, or the link is broken
You run a command you've used a hundred times, and the terminal spits back error while loading shared libraries: libfoo.so.1: cannot open shared object file. The program vanishes. You check the file manager, and the library is missing. Or the file exists, but it's a symlink pointing to a target that no longer exists. This happens after a partial upgrade, a manual file deletion, or a botched third-party RPM install. The system is confused about where its own parts live.
What's actually happening
Linux programs don't carry all their code inside a single binary. They rely on shared libraries. These are chunks of code stored in /usr/lib64 that multiple programs share to save space. The dynamic linker loads these libraries at runtime.
Think of a shared library like a reference book in a library. The program is a student. The student doesn't photocopy the whole book. The student gets a bookmark that points to the book's location. A symlink is that bookmark. If the book moves to a new shelf and the bookmark isn't updated, the student finds nothing. If the bookmark points to the wrong shelf, the student gets lost.
Libraries use a versioning scheme to manage updates. The real file has a full version number, like libfoo.so.1.2.3. Programs don't link to that directly. They link to the soname, which is the major version, like libfoo.so.1. The soname is a symlink pointing to the real file. When a package updates, it installs libfoo.so.1.2.4 and updates the libfoo.so.1 symlink to point to the new file. If that process breaks, the symlink dangles. The program asks for libfoo.so.1, the symlink points to nothing, and the loader fails.
The dynamic linker also uses a cache file at /etc/ld.so.cache to speed up lookups. Instead of scanning directories every time a program starts, the linker reads the cache. If you install a library manually or the cache gets out of sync, the linker won't see the new file even if it's on disk.
Run the upgrade first. The package manager fixes more problems than manual symlink surgery ever will.
The fix
Start with the package manager. Fedora tracks every file in /usr/lib64. If a library is missing or a symlink is broken, dnf knows which package owns it and how to restore it.
Here's how to refresh the repository metadata and apply any pending updates that might repair the issue.
sudo dnf upgrade --refresh
# --refresh forces dnf to ignore cached metadata and fetch fresh repo data
# This ensures you see the latest package versions and dependency fixes
# A stale cache can hide a package update that repairs the broken symlink
dnf upgrade --refresh is the normal weekly maintenance command. dnf system-upgrade is for crossing major Fedora releases. They are different commands. Don't conflate them.
If the update doesn't fix the error, the package might be corrupted or missing. Find the package that owns the missing library.
Here's how to search the repository metadata for the package that provides the missing file.
dnf provides /usr/lib64/libfoo.so.1
# dnf provides searches the repo metadata for the package that owns the path
# This works even if the file is currently missing from the filesystem
# The output shows the package name and the file list inside that package
If dnf provides returns a package name, reinstall that package. Reinstalling is safe. It downloads the package again and replaces all files without touching your configuration.
Here's how to reinstall the package to restore missing files and fix broken symlinks.
sudo dnf reinstall libfoo
# reinstall downloads the package again and replaces all files
# This restores missing files and fixes broken symlinks managed by the package
# dnf handles dependencies automatically, so related libraries get checked too
Reinstall the package. It's faster than hunting down which file belongs where.
Sometimes the library is installed, but the linker cache is stale. This happens if you installed a library manually or from a custom build directory. Refresh the cache.
Here's how to rebuild the shared library cache used by the dynamic linker.
sudo ldconfig
# ldconfig rebuilds the cache of shared libraries used by the dynamic linker
# The cache speeds up program startup by avoiding a full directory scan
# Run this after installing libraries from non-standard paths or custom builds
Run ldconfig. The cache is cheap to rebuild and expensive to ignore.
If you need to find broken symlinks across the system, use find. This is useful after a migration or if you suspect manual edits broke things.
Here's how to scan for dangling symlinks in the library directory.
sudo find /usr/lib64 -type l ! -exec test -e {} \; -print
# find locates symlinks where the target file does not exist
# -type l selects only symbolic links
# ! -exec test -e {} \; filters out links that point to valid targets
# This command prints paths of dangling links for inspection
Scan the system. A broken symlink is a symptom, not the disease. Find the root cause.
Verify it worked
Once you've applied the fix, confirm the binary can resolve all its dependencies.
Here's how to check which libraries a binary requires and which are missing.
ldd /path/to/binary | grep "not found"
# ldd lists all shared libraries required by the binary
# grep filters the output to show only missing dependencies
# An empty output means all libraries are resolved and the binary should run
Run ldd. If the list is clean, the binary is ready to run.
Common pitfalls and what the error looks like
Editing files in /usr/lib breaks package management. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. If you manually delete or move a library, dnf will complain during the next transaction. The fix is to reinstall the owning package.
Setting LD_LIBRARY_PATH is a temporary workaround, not a solution. This environment variable tells the linker to search extra directories before the system paths. It masks missing dependencies and causes subtle bugs where programs load the wrong version of a library. Use LD_LIBRARY_PATH only for debugging a specific build. Remove it from your shell profile.
Third-party RPMs often depend on library versions Fedora doesn't ship. If you install an RPM from a random website, you might see Error: Transaction test error: package libfoo conflicts with libbar. This means two packages claim to own the same file. Remove the third-party package and use the official repo version or a COPR repo. Don't force-install conflicting packages.
The RPM database rarely breaks. rpm --rebuilddb is a sledgehammer. Only use it if dnf reports database corruption errors. Running it unnecessarily wastes time and can mask the real problem.
If the library exists but you get a permission error, check SELinux. journalctl -t setroubleshoot shows the denial with a one-line summary. Read those before disabling SELinux. A missing library error is different from a permission denial. Fix the path first.
Trust the package manager. Manual file edits drift, snapshots stay.
When to use this vs alternatives
Use dnf upgrade --refresh when you suspect the issue is a stale cache or a missing update.
Use dnf reinstall when a specific package has corrupted files or broken symlinks.
Use ldconfig when you installed a library manually or from a custom build directory.
Use find with symlink checks when you need to audit the system for dangling links after a migration.
Use rpm --rebuilddb only when dnf explicitly reports database corruption errors.
Use ldd when you need to verify which libraries a binary requires and which are missing.