Resolving Python SSL: CERTIFICATE_VERIFY_FAILED Error
Problem Statement
When making HTTPS connections in Python, you might encounter this security-related error:
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)
This occurs when Python cannot verify the server's SSL/TLS certificate because it lacks access to the appropriate root certificates or can't locate its certificate bundle. Common causes include:
- Outdated/Missing root certificates
- Python being unable to find the system's CA bundle
- Corporate networks using custom certificates
- Environment misconfiguration
Recommended Solutions
Choose the solution appropriate for your environment.
1. Update Certifi and Configure Environment
Best for: All environments (most reliable solution)
pip install --upgrade certifi
Set environment variable permanently in your shell profile (.bashrc
, .zshrc
, etc.):
export SSL_CERT_FILE=$(python -c "import certifi; print(certifi.where())")
Temporary session-only use:
import os
import certifi
os.environ['SSL_CERT_FILE'] = certifi.where()
2. Use System Certificate Store via pip-system-certs
Best for: Environments with current certificate stores
pip install pip-system-certs
Restart your terminal/application after installation. This makes Python trust the system's certificate store.
3. Install Certificates (macOS Python.org Installation)
Best for: Official Python installers on macOS
# Replace X.X with your Python version
/Applications/Python\ X.X/Install\ Certificates.command
4. Point to Specific Certificate Bundle
Best when using custom/corporate certificates:
export SSL_CERT_FILE=/path/to/your/corporate_certs.pem
import requests
response = requests.get('https://example.com', verify='/path/to/your_certs.pem')
Linux System Certificate Management
Add custom certificates to system trust store:
sudo cp your_cert.pem /usr/share/ca-certificates/
sudo update-ca-certificates
Why These Solutions Work
The certifi
solution ensures Python uses a current certificate bundle maintained by certificate authorities. Setting SSL_CERT_FILE
points Python to the certificate location it needs to verify connections.
The pip-system-certs
approach is preferable when you want Python to trust the operating system's managed certificates.
Solutions to Avoid
Do not use these insecure workarounds:
# UNSAFE: Disables all certificate validation
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# Also unsafe in production
requests.get(url, verify=False)
Disabling certificate validation exposes your application to man-in-the-middle attacks and data interception.
Additional Considerations
- Homebrew Python (macOS): Use this enhanced workflow:
pip install certifi
echo 'export SSL_CERT_FILE=$(python -c "import certifi; print(certifi.where())")' >> ~/.zshrc
- Virtual Environments: Always run inside activated venv:
python -m venv .venv
source .venv/bin/activate
pip install --upgrade certifi
- Corporate Environments: Add your corporate certificate to
certifi
:
cat corporate-cert.crt >> $(python -m certifi)
- Time Synchronization: Ensure your system clock is accurate - SSL certificates expire at specific times.
Conclusion
Resolve SSL validation errors by ensuring Python can access current certificate authorities. The recommended approach is installing and configuring certifi
with the SSL_CERT_FILE
environment variable. Alternatives include using system certificates via pip-system-certs
or leveraging OS certificate management tools. Avoid disabling SSL verification entirely in production environments to maintain security.