Skip to content
Latchkey

PDM/uv Build From Source Fails - Missing Compiler or Headers in CI

PDM and uv install from wheels when available, but fall back to a source build when no compatible wheel exists. That build needs a compiler and the dependency’s system headers - which a slim runner image often lacks.

What this error means

A pdm install/pdm sync or uv sync/uv pip install fails while building a native dependency from sdist, with a compiler "not found" or a fatal error: <header>.h: No such file or directory. A glibc image with wheels avoids it entirely.

pdm/uv output
Building wheel for ujson (pyproject.toml): finished with status 'error'
  ujson.c:1:10: fatal error: Python.h: No such file or directory
error: command 'gcc' failed: No such file or directory

Common causes

No compatible wheel, so a source build runs

On musl/Alpine, an exotic arch, or a brand-new Python, the dependency has no prebuilt wheel, so PDM/uv must compile it from sdist.

Compiler or dev headers missing

The source build needs gcc/clang plus the package’s headers (and python3-dev). A slim image without them fails the build.

How to fix it

Install the toolchain and headers

Terminal
# Debian/Ubuntu
apt-get update && apt-get install -y build-essential python3-dev
# Alpine
apk add --no-cache gcc musl-dev python3-dev
pdm install   # or: uv sync

Prefer wheels to skip the build

Use a glibc base so manylinux wheels apply, or constrain the resolver to binary-only.

Terminal
# uv: only use prebuilt wheels
uv pip install --only-binary :all: -r requirements.txt

How to prevent it

  • Prefer glibc images so PDM/uv install from wheels.
  • Bake a compiler and common dev headers into images that build from source.
  • Pin Python to a version with wheel coverage for native deps.

Related guides

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