Your Python was built without working OpenSSL bindings — typical for source builds, pyenv on newer distros, or an interpreter built against a dev package that isn't installed. Reinstalling the interpreter (not pip) fixes it.
Source builds link libssl at compile time: missing libssl-dev (Debian) or a mismatched OpenSSL version (CentOS 1.0 vs Python needing 1.1+) leaves the ssl module absent. python -c 'import ssl' fails.
pyenv install compiles from source: without openssl-devel and friends, the build succeeds minus TLS, and every pip network call dies. Same signature, same fix class.
python -c 'import ssl' 2>&1 ; python -c 'import _ssl' 2>&1 | tail -1
sudo apt install -y libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev # Debian/Ubuntu
pyenv install <version> # or for source: ./configure --with-ensurepip=install && make && sudo make altinstall
sudo apt install python3 python3-pip python3-venv # linked correctly by the distro maintainers
This is an interpreter problem, not a pip problem: no pip flag fixes a Python without TLS. Reinstall the interpreter after fixing the dev packages. python -c 'import ssl' is the 5-second test before any deeper debugging — the output distinguishes missing-module (rebuild) from import errors (environment).
You can install wheels, but without ssl the interpreter is permanently hobbled: https, TLS, hashlib features all misbehave. Fix the build once and everything downstream heals.
The compile logs a warning about the missing ssl module but still completes. Nobody reads build logs on success — which is exactly why this error appears later, at first pip use.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.