Skip to content
Latchkey

Python ImportError: a Shared Library on LD_LIBRARY_PATH Not Found in CI

A compiled extension imported, but a library it depends on lives in a non-standard prefix the dynamic loader does not search. The fix is to put that directory on LD_LIBRARY_PATH (or register it with ldconfig), not to reinstall the package.

What this error means

Importing a package fails with ImportError: lib<name>.so.N: cannot open shared object file even though the file exists somewhere on disk under a custom prefix (CUDA, a self-built library, a conda lib dir). Adding the directory to LD_LIBRARY_PATH fixes it.

Python traceback
ImportError: libcudart.so.12: cannot open shared object file: No such file or directory
# the file exists, just not on the loader search path:
$ find / -name 'libcudart.so.12' 2>/dev/null
/usr/local/cuda-12/lib64/libcudart.so.12

Common causes

Library in a non-standard prefix

The dependent .so is under a custom location (e.g. /usr/local/cuda/lib64) that is not in the default loader search path or ld.so.conf.

LD_LIBRARY_PATH not propagated to the step

A previous step set LD_LIBRARY_PATH, but each CI step is a fresh shell, so a later step that imports the package no longer has it.

How to fix it

Add the library directory to LD_LIBRARY_PATH

Terminal
export LD_LIBRARY_PATH="/usr/local/cuda-12/lib64:${LD_LIBRARY_PATH}"
python -c "import the_package"

Persist it across CI steps

On GitHub Actions, write it to the job environment so later steps inherit it.

.github/workflows/ci.yml
- run: echo "LD_LIBRARY_PATH=/usr/local/cuda-12/lib64:${LD_LIBRARY_PATH}" >> "$GITHUB_ENV"

Or register the path with ldconfig

Terminal
echo "/usr/local/cuda-12/lib64" > /etc/ld.so.conf.d/cuda.conf
ldconfig

How to prevent it

  • Register custom library prefixes with ldconfig in the runner image.
  • Persist LD_LIBRARY_PATH via $GITHUB_ENV, not a single step.
  • Prefer wheels that bundle their native libraries to avoid loader path issues.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →