Fix "error while loading shared libraries: cannot open shared object file"
Find which package ships the missing file and install it. On Ubuntu/Debian:
sudo apt install apt-file
sudo apt-file update
apt-file search libfoo.so.1
sudo apt install <package-from-output>
Fedora: dnf provides '*/libfoo.so.1'. Arch: sudo pacman -Fy then pacman -F libfoo.so.1. If you installed the library yourself under /usr/local/lib, run sudo ldconfig.
What the error means
$ ./myapp
./myapp: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
Most Linux programs are dynamically linked: they do not contain common code such as OpenSSL or the C++ runtime, but list the libraries they need. Before main() runs, the dynamic loader (ld-linux) looks for each one in the directories cached in /etc/ld.so.cache, plus any in LD_LIBRARY_PATH or the binary's own RPATH. If one is missing, the loader stops with this message and names the first file it could not find. The program itself never started.
The number after .so (the soname version) matters: libssl.so.1.1 and libssl.so.3 are different, incompatible libraries.
Step 1: list every missing library
The error shows only the first missing library. See them all:
ldd ./myapp | grep 'not found'
Example output:
libssl.so.1.1 => not found
libcrypto.so.1.1 => not found
ldd can execute code from the program in some cases. For files you do not trust, read the required libraries without running anything: readelf -d ./myapp | grep NEEDED or objdump -p ./myapp | grep NEEDED.
Cause 1: the library package is not installed (most common)
Search your distro's file index for the exact file name and install the package that contains it:
| Distro | Find the package | Install |
|---|---|---|
| Ubuntu, Debian, Mint | apt-file search libfoo.so.1 | sudo apt install libfoo1 |
| Fedora | dnf provides '*/libfoo.so.1' | sudo dnf install foo-libs |
| Arch | sudo pacman -Fy, then pacman -F libfoo.so.1 | sudo pacman -S foo |
| openSUSE | zypper search --provides libfoo.so.1 | sudo zypper install libfoo1 |
Debian and Ubuntu name library packages after the soname (libfoo.so.1 lives in libfoo1, possibly with a t64 suffix on current releases, such as libssl3t64). Fedora usually ships the library in the main package or a -libs subpackage. The package manager comparison lists more equivalents.
If the search finds nothing, the version the program wants is not shipped by your release at all; that is cause 3.
Cause 2: the library is installed but not where the loader looks
Libraries you compiled yourself or that came with a vendor tarball often land in /usr/local/lib, /opt/vendor/lib or next to the binary. Check whether the file exists somewhere:
sudo find / -name 'libfoo.so*' 2>/dev/null
ldconfig -p | grep libfoo
If find locates it but ldconfig -p does not list it, register the directory and rebuild the cache:
echo '/opt/vendor/lib' | sudo tee /etc/ld.so.conf.d/vendor.conf
sudo ldconfig
After make install into /usr/local/lib, running sudo ldconfig alone is enough on Debian and Ubuntu, which list that directory in /etc/ld.so.conf.d/libc.conf. On other distros check cat /etc/ld.so.conf /etc/ld.so.conf.d/* and add /usr/local/lib (or /usr/local/lib64) as above if it is missing.
For a single program you can instead set the path at launch, typically in a wrapper script:
LD_LIBRARY_PATH=/opt/vendor/lib /opt/vendor/bin/app
Do not export LD_LIBRARY_PATH globally in ~/.bashrc; it affects every program you run and causes confusing breakage. Note that sudo strips it.
Cause 3: the program wants an older (or newer) version
A program built years ago may need libssl.so.1.1, libffi.so.7 or libncurses.so.5, which current distros replaced with newer sonames. Options, best first:
- Get a newer build of the program for your release, or its distro package.
- Install a compatibility package if your distro offers one: search for it (
apt search libncurses5,dnf search compat,pacman -Ss openssl-1.1). Arch keeps some old versions such asopenssl-1.1in the repositories or AUR. - Use a container or Flatpak/AppImage that bundles its libraries:
distrobox create --image ubuntu:20.04gives you an older userland that shares your home directory. See installing .deb, .rpm and AppImage files.
Creating libssl.so.1.1 as a link to libssl.so.3 may silence the error but the ABI differs, so the program can crash, corrupt data or skip security checks. Never copy libraries from another distro release into /usr/lib either; package updates will overwrite or conflict with them.
If the message says version 'GLIBC_2.xx' not found rather than "cannot open shared object file", the C library is present but too old: see GLIBC version not found.
Cause 4: a 32-bit program on a 64-bit system
Older games, proprietary tools and some printer drivers are 32-bit. file ./myapp reports ELF 32-bit. They need 32-bit libraries, which 64-bit installs lack. A related error is wrong ELF class: ELFCLASS64, meaning the loader found a 64-bit library for a 32-bit program. Install the 32-bit variant:
# Ubuntu, Debian, Mint
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libfoo1:i386
# Fedora
sudo dnf install foo-libs.i686
# Arch: enable [multilib] in /etc/pacman.conf, then
sudo pacman -Syu lib32-foo
A 32-bit binary with no 32-bit loader at all fails with a misleading "No such file or directory" even though the file exists; installing libc6:i386 (Debian/Ubuntu), glibc.i686 (Fedora) or lib32-glibc (Arch) fixes that.
Distro-specific notes
- Arch: this error after updating usually means a partial upgrade (installing one package with
pacman -Sy pkgwithout upgrading the rest). Runsudo pacman -Syu; AUR packages built against the old library must be rebuilt. - Fedora: after a release upgrade, third-party RPMs built for the previous release can lose their libraries; reinstall them from a repo that matches the new release.
- Ubuntu/Debian:
sudo apt --fix-broken installpulls in missing dependencies for packages installed from.debfiles. - openSUSE:
zypperlibrary packages follow the soname too (libfoo1), so searching for the soname number usually finds them.
How to prevent it
- Install software through the package manager or with
apt install ./file.deb/dnf install ./file.rpmso dependencies are resolved. - Prefer Flatpak or AppImage for proprietary or old software; they carry their own libraries.
- Run
sudo ldconfigafter every manual library install, and keep manual installs under/usr/localor/opt, never in/usr/lib.
Frequently asked questions
How do I find which package provides a missing .so file?
On Ubuntu/Debian use apt-file search libfoo.so.1 (after sudo apt-file update), on Fedora dnf provides '*/libfoo.so.1', on Arch pacman -F libfoo.so.1 and on openSUSE zypper search --provides libfoo.so.1.
Should I symlink libssl.so.3 to libssl.so.1.1?
No. A different number after .so means an incompatible ABI; the program may crash or behave insecurely. Install the matching compatibility package, use a newer build of the program, or run it in a container.
Why does the program work as my user but not with sudo?
sudo resets the environment, so LD_LIBRARY_PATH is dropped. Register the directory with ldconfig instead, or pass the variable explicitly: sudo env LD_LIBRARY_PATH=/opt/app/lib /opt/app/bin/app.
What does ldconfig do?
It rebuilds /etc/ld.so.cache, the index the dynamic loader uses to find libraries in the standard directories and those listed in /etc/ld.so.conf.d/. Run sudo ldconfig after installing libraries by hand.
Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.