Skip to content
Latchkey

TensorFlow "could not load dynamic library libcudart" in CI

The GPU TensorFlow build dlopens CUDA libraries at import; on a CPU-only runner the CUDA runtime is absent, so it logs that it could not load libcudart.so and falls back to CPU - or fails if code requires the GPU.

What this error means

TensorFlow logs "Could not load dynamic library 'libcudart.so.12'; dlerror: libcudart.so.12: cannot open shared object file". On a CPU runner this is often a warning; GPU-required code then fails.

python
Could not load dynamic library 'libcudart.so.12'; dlerror: libcudart.so.12:
cannot open shared object file: No such file or directory

Common causes

A CPU-only runner with the GPU TensorFlow build

CI has no NVIDIA GPU or CUDA toolkit, but tensorflow (GPU variant) tries to load CUDA libraries that are not present.

A CUDA version mismatch on a GPU runner

The installed CUDA runtime version differs from what the TensorFlow build expects, so the exact libcudart.so.N is missing.

How to fix it

Install the CPU build for CPU runners

On runners without a GPU, use the CPU package so no CUDA libraries are needed.

Terminal
pip install tensorflow-cpu

Match CUDA to the TensorFlow build on GPU runners

On a GPU runner, install the CUDA toolkit version the TensorFlow release requires so libcudart resolves.

Terminal
# pin the TF version to the CUDA stack present on the GPU runner
pip install "tensorflow==2.16.*"

How to prevent it

  • Use tensorflow-cpu on CPU-only CI jobs.
  • Pin TensorFlow to the CUDA toolkit version available on GPU runners.
  • Bake the matching CUDA libraries into a custom GPU runner image.

Related guides

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