Table of Contents
ToggleSummary:
I have seen this error when the Python requests library or the underlying urllib3 package cannot verify a server’s SSL certificate against your local trust store which can be seen in corporate proxy environments, local dev setups, or systems with outdated certificate bundles.
What This Error Means
When we try to make an HTTPS request. Python makes sure that the server we are talking to is who they claim to be by verifying the server’s SSL certificate against a “bundle” of trusted Root Certificate Authorities (CAs) stored on your machine.
If the check we made fails then Python throws[SSL: CERTIFICATE_VERIFY_FAILED] exception and our script crashes
We see this error usually in
- While running data scraping scripts or automation.
- During API development and testing.
- While fetching datasets from HTTPS sources.
- Inside Docker containers or Cloud Functions where the CA bundle might be missing or outdated.
Replicating the error
import requests
url = "https://expired.badssl.com/"
response = requests.get(url)
print(response.text)
SSLCertVerificationError Traceback (most recent call last)
/usr/local/lib/python3.12/dist-packages/urllib3/connectionpool.py in _make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
463 try:
--> 464 self._validate_conn(conn)
465 except (SocketTimeout, BaseSSLError) as e:
SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1010)
SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1010)
MaxRetryError: HTTPSConnectionPool(host='expired.badssl.com', port=443): Max retries exceeded with url: /
What Causes This Python Error?
Primarily there are three main culprits behind this frustrating traceback
1. Outdated certifi Bundle (Most Common)
The requests library in Python uses a package called certifi to locate trusted certificates. If our certifi package is outdated, it may not acknowledge newly issued certificates from authorities such as Let’s Encrypt.
import requests
# This triggers the error if your CA bundle is outdated
response = requests.get("https://example-with-new-ca.com")
2. Corporate Proxies and SSL Inspection
In office settings, the IT department uses a “Middleman” proxy to inspect traffic. This proxy replaces the website’s certificate with its own self-signed certificate. Since Python doesn’t know your company’s internal certificate, it rejects the connection.
3. Missing Local Issuer (macOS/Windows specific)
In macOS, Python often doesn’t automatically install the needed certificates. Python sometimes fails to look into the Windows Certificate Store, relying only on its own internal file.
How I Fixed This Error (Step-by-Step)
I recently faced this error while building an API aggregator. Here is the exact path I took to solve it without compromising security.
Step 1: Identify the Root Cause
Let’s first determine if the issue is in our local environment. Run this in your terminal:
Bash
python -m certifi
If this provides a path but your requests still fail, your certifi bundle is likely missing the specific CA for the site you want.
Step 2: Apply the Fix (The “Right” Way)
Don’t just disable verification! Instead, instruct Python to use the latest certificates or your company’s specific certificate.
Standard Fix: Update your CA bundle.
Bash
pip install --upgrade certifi
Corporate/Self-Signed Fix:
If you have a .pem certificate file from your IT team, point to it directly:
import requests
# Path to your company's root certificate
custom_cert = "/path/to/company-root-ca.pem"
# Corrected code
response = requests.get("https://internal-api.com", verify=custom_cert)
print("Success!")
Step 3: Verify the Fix
To ensure it’s fixed globally for your project without hardcoding paths, set an environment variable in your terminal:
Bash
export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem
Then rerun your script. If it works, the environment variable is handling the “trust” issue for you.
Common Mistakes That Trigger This Error
- The “Dirty” Fix (verify=False): This is a common mistake. Setting verify=False makes your app vulnerable to Man-in-the-Middle (MitM) attacks.
- Forgetting urllib3 Warnings: If you must use verify=False for a quick test, people often forget to suppress the annoying warnings that clutter their logs.
- System vs. Venv: we might update certifi in our global Python but run the script in a Virtual Environment (venv) where the old version still exists.
- Incomplete Chains: If the server is misconfigured and it is sending only the site certificate without the “intermediate” certificates
How to Prevent This Error in Production
- Pin and Update Certifi: place certifi in your requirements.txt and keep it updated via CI/CD.
- Use pip-system-certs (Windows): If you are on Windows, pip install pip-system-certs allows Python to use the official Windows Certificate Store automatically.
Docker Best Practices:
apt-get update && apt-get install -y ca-certificates && update-ca-certificates
Frequently Asked Questions (FAQ)
Is verify=False okay for production?
No. Never do that as it allows anyone from the same network to intercept and read your data which may include passwords and API keys.
How do I fix this on macOS specifically?
Navigate to applications folder -> Python 3.x folder -> Double-click the file named Install Certificates.command. This is a common Mac-specific fix.
Why does it work in my browser but not in Python?
Chrome and Firefox have their own certificate stores. Python relies on the certifi package or our system’s OpenSSL, which may be less frequently updated.
Author’s Note
I saw this error while working on a data pipeline which pulled from government API. After debugging, I realized the issue was not from my side of code. The API had switched to a new certificate provider that wasn’t in my 6-month-old certifi bundle.
Note: Always try pip install –upgrade certifi first as it solves 90% of these cases in seconds. If you’re in a corporate environment, REQUESTS_CA_BUNDLE is your best friend.
Tested on: Python 3.10, 3.11, 3.12, 3.13
OS: Windows 11, macOS Sequoia, Ubuntu 24.04
Reference SSL Cert Verification
You can read our other blog on ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed,
AWS cli ssl certificate_verify_failed and
pip install ssl certificate_verify_failed.

