How to Install Python cryptography in CI Without Rust Build Failures
Modern cryptography builds its core in Rust, so on a platform with no wheel the install suddenly needs cargo and OpenSSL headers - a nasty surprise in CI.
The cryptography package ships manylinux wheels for mainstream platforms, and on those there is nothing to build. On Alpine/musl, a brand-new Python, or an uncommon arch, pip falls back to a source build that needs a Rust toolchain plus the OpenSSL dev headers - the common cause of CI breakage.
Why it fails in CI
When no wheel matches, pip compiles cryptography from source. Recent versions build a Rust extension, so the build requires cargo/rustc and libssl-dev. Slim and Alpine images have neither, so the build fails with a Rust or OpenSSL error.
error: can't find Rust compiler/cargo: command not found.fatal error: openssl/opensslv.h: No such file or directory.- On musl/Alpine, missing
musl-dev,libffi-dev, oropenssl-dev.
Install it reliably
Stay on the wheel: use a glibc base image (the official python: images, not Alpine) and a Python version with a published wheel, and force-binary so a missing wheel fails loudly. If you truly must build, install Rust and the OpenSSL/FFI headers.
# Prefer the wheel; no Rust, no OpenSSL build
pip install --only-binary=:all: cryptography
# Source build fallback (Debian/Ubuntu): Rust + OpenSSL + FFI
apt-get update && apt-get install -y build-essential libssl-dev libffi-dev python3-dev
curl https://sh.rustup.rs -sSf | sh -s -- -y && . "$HOME/.cargo/env"
pip install cryptographyCache & speed
The Rust build is slow. Avoid it by using wheels. If you cannot, cache the cargo registry and ~/.cache/pip to keep rebuilds down, and bake the toolchain into the image.
- uses: actions/cache@v4
with:
path: |
~/.cache/pip
~/.cargo/registry
key: pip-crypto-${{ hashFiles('requirements*.txt') }}Common errors
| Error | Cause | Fix |
|---|---|---|
| can't find Rust compiler | No Rust toolchain | Install rustup, or use a wheel |
| openssl/opensslv.h not found | OpenSSL headers missing | apt-get install libssl-dev |
| ffi.h not found | libffi headers missing | apt-get install libffi-dev |
| No matching distribution (musl) | No musl wheel | Use a glibc base image |
Key takeaways
- Use a glibc base image so the manylinux wheel installs with no build.
- --only-binary makes a missing wheel fail loudly instead of triggering Rust.
- If you must build: rustup + libssl-dev + libffi-dev.