How to Fix CERTIFICATE_VERIFY_FAILED in Python
Tell a missing CA bundle from company inspection or a broken site chain, then apply the matching fix.
Updated
TL;DR
CERTIFICATE_VERIFY_FAILED means Python's ssl module could not trace the site's certificate to a root in the CA bundle your client loads, so Python itself ended the connection. The fastest fix is to give Python a current bundle, plus your company's root if your network inspects HTTPS.
What the error looks like in each client
The number after _ssl.c changes with the Python version; host and port come from your URL.
| Where | What you see |
|---|---|
| Python urllib (3.12) | urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)> |
| Python requests | requests.exceptions.SSLError: HTTPSConnectionPool(host='localhost', port=54387): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)'))) |
| httpx, root sent by an inspection proxy | httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1000) |
| aiohttp | aiohttp.client_exceptions.ClientConnectorCertificateError: Cannot connect to host localhost:54387 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)')] |
| Python 3.13 or later, older CA certificate | urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical (_ssl.c:1081)> |
Why this happens
Python found no trusted authority behind the certificate the site sent.
A pip-installed requests checks only certifi's bundle, not the store your browser reads, so a root added to your system does not count. A missing CA file or an intermediate the server never sends breaks the chain too.
Diagnose your CERTIFICATE_VERIFY_FAILED first
Each check narrows the cause to your Python, your network or the site, before you change anything.
Open the same URL in Chrome on this computer; if it shows "Your connection is not private", the site, network or device fails Chrome too.
Request two unrelated HTTPS sites from the same Python environment; if both fail, the cause is your CA bundle or network, not either site.
On macOS or Linux, print ssl.get_default_verify_paths(); if cafile and capath are both None, urllib and aiohttp have no roots to check against.
Read how the error ends; "self-signed certificate in certificate chain" means the server or a network proxy sent a root your bundle lacks.
Run openssl s_client -showcerts -servername host -connect host:443; if only entry 0 appears, issued by a CA, the server skips its intermediate.
Solutions ranked by effectiveness
All three fixes change only your machine, starting with the bundle Python loads.
- Most common fix
Install or update Python's CA bundle
Applies when every HTTPS site fails from Python. A python.org install on macOS ignores the Keychain and gets its default roots from its Install Certificates script, and requests relies on certifi.
In Finder, open the Python 3.x folder in Applications that matches your version.
Double-click Install Certificates.command and wait for "update complete" in Terminal.
Elsewhere, for requests, run python3 -m pip install --upgrade certifi in the failing environment.
- Check next
Add your company's root to a bundle
Applies on a work network that inspects HTTPS, where every site fails the same way. Get the inspection root from IT as a PEM file and combine it with certifi's roots.
# pip install requests certifi import certifi import requests bundle = "ca-bundle.pem" with open(bundle, "w") as out: for path in (certifi.where(), "company-root.pem"): with open(path) as f: out.write(f.read() + "\n") r = requests.get("https://example.com/", verify=bundle) print(r.status_code) - For developers
Verify through the operating system with truststore
When Chrome on this computer opens the site, truststore lets Python 3.10 or later verify through the operating system, which trusts roots IT installed and, on macOS and Windows, fetches a missing intermediate.
# pip install truststore requests import truststore truststore.inject_into_ssl() import requests r = requests.get("https://example.com/") print(r.status_code)
Stop the CERTIFICATE_VERIFY_FAILED from coming back
Habits that keep a working bundle working through upgrades, new code paths and new Python versions.
Leave certifi's cacert.pem unedited; the certifi project supports no additions or removals to its trust store.
Test HTTPS calls on Python 3.13 or later before you upgrade; its strict checks reject some older certificates.
In code that sends prepared requests, pass verify= explicitly; that flow ignores REQUESTS_CA_BUNDLE.
Related errors
Learn more
FAQ
One proxy entry for Python clients
Geonode's http://user:pass@host:port entry goes into requests, httpx and aiohttp proxy settings.


