Python "ssl.SSLCertVerificationError" with requests in CI
By Kaveh Alemi·Latchkey
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.
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.