Skip to content

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

Choose the solution appropriate for your environment.

1. Update Certifi and Configure Environment

Best for: All environments (most reliable solution)

bash
pip install --upgrade certifi

Set environment variable permanently in your shell profile (.bashrc, .zshrc, etc.):

bash
export SSL_CERT_FILE=$(python -c "import certifi; print(certifi.where())")

Temporary session-only use:

python
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

bash
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

bash
# 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:

bash
export SSL_CERT_FILE=/path/to/your/corporate_certs.pem
python
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:

bash
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:

python
# 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

  1. Homebrew Python (macOS): Use this enhanced workflow:
bash
pip install certifi
echo 'export SSL_CERT_FILE=$(python -c "import certifi; print(certifi.where())")' >> ~/.zshrc
  1. Virtual Environments: Always run inside activated venv:
bash
python -m venv .venv
source .venv/bin/activate
pip install --upgrade certifi
  1. Corporate Environments: Add your corporate certificate to certifi:
bash
cat corporate-cert.crt >> $(python -m certifi)
  1. 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.