Encountering an SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] while writing Python web scrapers, automation scripts, or API integrations can instantly halt your workflow. This error occurs when Python’s underlying transport layer cannot cryptographically verify the SSL/TLS certificate presented by the target server. It acts as a crucial security measure to protect your environment from man-in-the-middle (MITM) attacks, but it frequently triggers false positives due to outdated local certificate bundles, corporate interception proxies, or self-signed certificates.
Learning how to fix SSL CERTIFICATE_VERIFY_FAILED errors in Python requests safely requires distinguishing between development workarounds and production-grade security practices. This guide breaks down the core causes of SSL verification failures and provides actionable, step-by-step solutions to resolve them.
Key Takeaways
- The Root Cause: The error happens because Python’s
requestslibrary relies on trusted Certificate Authorities (CAs) that may be missing, outdated, or intercepted by a local corporate network proxy. - Avoid
verify=Falsein Production: While settingverify=Falseprovides an immediate local workaround, it disables encryption validation entirely and leaves applications vulnerable to security exploits. - Update the
certifiPackage: Frequently, the easiest fix is ensuring your Python environment’s root certificate bundle is fully updated to the latest standard. - Handle Enterprise Proxies Correctly: Corporate SSL-inspection firewalls require injecting custom enterprise root
.pemcertificates into your environment paths or explicit request parameters.
Why the “SSL: CERTIFICATE_VERIFY_FAILED” Error Occurs
Before implementing a fix, it helps to understand why Python raises this exception. When your script executes an HTTPS request using the popular requests library, the system performs a cryptographic handshake with the remote server.
┌────────────────────────────────────────────────────────────────────────┐
│ PYTHON SSL VERIFICATION HANDSHAKE FAILURE │
├───────────────────────────────┬────────────────────────────────────────┤
│ TRIGGER CONDITION │ UNDERLYING REASON │
├───────────────────────────────┼────────────────────────────────────────┤
│ Outdated Python/OpenSSL │ Local system trust store lacks modern │
│ │ root certificates. │
├───────────────────────────────┼────────────────────────────────────────┤
│ Corporate SSL Proxy │ Firewall intercepts traffic and signs │
│ │ with an untrusted internal CA cert. │
├───────────────────────────────┼────────────────────────────────────────┤
│ Self-Signed Certificates │ Target domain uses a private key not │
│ │ recognized by public CAs. │
├───────────────────────────────┼────────────────────────────────────────┤
│ Expired Domain Certificate │ Target server's SSL certificate has │
│ │ passed its expiration date. │
└───────────────────────────────┴────────────────────────────────────────┘
If the root certificate authority that signed the server’s certificate is not present in Python’s trusted bundle—or if your network traffic is being decrypted by a corporate gateway—the cryptographic check fails immediately.
Solution 1: Update the certifi Package
Python’s requests library depends on the certifi package to provide a curated collection of root certificates. If your local development environment runs an older version of certifi, it may fail to validate domains using modern intermediate certificates.
Step 1: Upgrade Certifi and Requests via Pip
Open your terminal and ensure your packages are running the latest versions:
Bash
pip install --upgrade requests certifi
Step 2: Reference Certifi Explicitly in Your Code
Pass certifi.where() directly into your request’s verify parameter to ensure Python uses the updated bundle:
Python
import requests
import certifi
url = "https://example.com"
response = requests.get(url, verify=certifi.where())
print(response.status_code)

Solution 2: Configure Custom CA Bundles for Corporate Proxies
If you are developing inside an enterprise network, your company firewall likely intercepts HTTPS traffic to scan for malware, re-signing requests with an internal corporate Root CA. Because Python does not trust your company’s private certificate authority by default, it throws a verification error.
Step 1: Export Your Corporate Certificate
Obtain your company’s root certificate file from your IT security team in .pem or .crt format (e.g., corp-root-ca.pem).
Step 2: Set the REQUESTS_CA_BUNDLE Environment Variable
You can configure your operating system environment so that every Python script automatically trusts your corporate certificate without modifying individual code files:
- On Linux / macOS:Bash
export REQUESTS_CA_BUNDLE="/path/to/corp-root-ca.pem" - On Windows (PowerShell):PowerShell
$env:REQUESTS_CA_BUNDLE="C:\path\to\corp-root-ca.pem"
Step 3: Pass the Certificate Path Explicitly in Code
Alternatively, target the local certificate file directly inside your script:
Python
import requests
url = "https://internal.enterprise-app.com"
cert_path = "/path/to/corp-root-ca.pem"
response = requests.get(url, verify=cert_path)
print(response.json())

Solution 3: Handle Self-Signed Certificates in Local Development
When testing against local microservices or staging environments utilizing self-signed certificates, public CAs will always reject the handshake.
You can explicitly point your request to your local development certificate file:
Python
import requests
local_url = "https://localhost:8443/api/v1/status"
ca_cert = "/certs/local-dev-root.crt"
# Bypass verification against public CAs by trusting the local cert file
response = requests.get(local_url, verify=ca_cert)
print(response.text)
Solution 4: The Development Workaround (verify=False)
If you are working in a strictly isolated local sandbox and need a quick workaround for debugging, you can disable SSL verification entirely by setting verify=False:
Python
import requests
url = "https://self-signed.badssl.com/"
# WARNING: Disables SSL certificate verification
response = requests.get(url, verify=False)
print(response.text)
Crucial Security Warning: Setting
verify=Falsedisables cryptographic certificate checks, exposing your script to Man-in-the-Middle (MITM) attacks. Never useverify=Falsein production environments or when transmitting sensitive user data. When enabled, Python will also raise anInsecureRequestWarningin your console logs.

Summary Checklist for Troubleshooting SSL Errors
Use this quick troubleshooting flow when diagnosing SSLError exceptions in Python:
- Are you on a corporate network? → Export your company’s root
.pemcertificate and setREQUESTS_CA_BUNDLE. - Is your local certifi package outdated? → Run
pip install --upgrade certifiand passverify=certifi.where(). - Is the target server using a self-signed cert? → Download the
.crtfile and pass its file path into theverifyparameter. - Is this purely a local development test? → Use
verify=Falsetemporarily, but never deploy it to production.
Conclusion
Resolving the SSL: CERTIFICATE_VERIFY_FAILED error in Python requests requires balancing debugging speed with strict network security standards. While setting verify=False offers a fast temporary workaround for local testing,production applications should always maintain cryptographic validation by updating certifi bundles, configuring custom corporate CA paths, or trusting explicit self-signed certificates. By applying these structured solutions, you can maintain secure, uninterrupted API integrations across all environments.
Frequently Asked Questions (FAQs)
What does verify=False do in Python requests?
Setting verify=False tells the requests library to skip SSL/TLS certificate verification entirely. While this successfully bypasses the verification error, it leaves your application vulnerable to interception and man-in-the-middle attacks.
How do I fix SSL errors behind a corporate proxy?
Corporate firewalls often intercept and re-sign HTTPS traffic using private internal certificates. To fix this, export your company’s root certificate as a .pem file and either pass its file path to verify='/path/to/ca.pem' or set the REQUESTS_CA_BUNDLE environment variable.
Why does my script work on my local machine but fail on a production server?
Production servers often run isolated Linux environments with outdated operating system trust stores, older OpenSSL versions, or restricted outbound network policies. Ensuring that both certifi and your system’s OpenSSL packages are fully updated on the server resolves most environment-specific discrepancies.
1 thought on “How to Fix “SSL: CERTIFICATE_VERIFY_FAILED” Errors in Python Requests”