Skip to content
Latchkey

Python "ssl.SSLCertVerificationError" with requests in CI

requests opened a TLS connection but could not verify the server certificate chain against the runner's CA bundle. The handshake aborts before any HTTP response - usually a missing CA, a proxy-injected certificate, or a stale certifi.

What this error means

An HTTP call fails with "requests.exceptions.SSLError: ... [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate".

python
requests.exceptions.SSLError: HTTPSConnectionPool(host='api.example.com', port=443):
Max retries exceeded with url: /v1/data (Caused by SSLError(SSLCertVerificationError(
1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate')))

Diagnose it: is it the build backend or a missing system library?

Python packaging failures in CI split into build-backend configuration problems and missing system headers. The traceback usually points at the backend even when the real cause is an absent -dev package.

Terminal
python -m pip install --upgrade pip build
python -m build --wheel 2>&1 | tail -40

# a compiler error naming a .h file is a system dependency, not a Python one
#   e.g. "Python.h: No such file" -> python3-dev
#        "openssl/ssl.h"          -> libssl-dev

Common causes

A proxy or private host presents an untrusted certificate

A TLS-inspecting proxy or internal endpoint serves a certificate signed by a CA not in the runner trust store.

A missing or outdated CA bundle

A slim image without ca-certificates, or a stale certifi, cannot validate the chain.

How to fix it

Point requests at the right CA bundle

Trust the corporate or system CA explicitly instead of disabling verification.

Terminal
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
python app.py

Refresh the CA store and certifi

Update system certificates and the certifi package so modern chains validate.

Terminal
sudo apt-get update && sudo apt-get install -y ca-certificates
pip install --upgrade certifi

How to prevent it

  • Install the corporate CA into the runner trust store, not into code.
  • Keep ca-certificates and certifi current in custom images.
  • Never set verify=False as a permanent fix.

Frequently asked questions

What causes Python "ssl.SSLCertVerificationError" with requests in CI?
There are 2 common causes: a proxy or private host presents an untrusted certificate and a missing or outdated ca bundle. A TLS-inspecting proxy or internal endpoint serves a certificate signed by a CA not in the runner trust store.
How do I fix Python "ssl.SSLCertVerificationError" with requests in CI?
There are 2 fixes depending on which cause you have: point requests at the right ca bundle and refresh the ca store and certifi. Work through them in order, since the first is the most common.
What does Python "ssl.SSLCertVerificationError" with requests in CI actually mean?
An HTTP call fails with "requests.exceptions.SSLError: ...
How do I stop Python "ssl.SSLCertVerificationError" with requests in CI happening again?
Install the corporate CA into the runner trust store, not into code. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card