# How to Fix Python SSL Certificate Verify Failed

SSL certificate verification errors occur when Python cannot validate the SSL certificate of a remote server. This guide covers common causes and solutions.

Introduction

This article covers troubleshooting steps and solutions for How to Fix Python SSL Certificate Verify Failed. The error typically occurs in production environments and can cause service disruptions if not addressed promptly.

Symptoms

requests Library

text
requests.exceptions.SSLError: HTTPSConnectionPool(host='example.com', port=443):
Max retries exceeded with url: /api/data (Caused by SSLError(
SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)')))

urllib Library

text
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)>

httpx Library

text
httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed: self signed certificate

aiohttp Library

text
aiohttp.client.ClientConnectorCertificateError:
Cannot connect to host example.com:443 ssl:True
[SSLCertVerificationError: (1, 'certificate verify failed')]

Common Causes

  1. 1.Self-signed certificates - Server uses certificate not signed by trusted CA
  2. 2.Expired certificates - Server certificate has expired
  3. 3.Missing CA bundle - Python cannot find root certificates
  4. 4.Corporate proxy - Proxy intercepts SSL with custom certificate
  5. 5.Certificate chain incomplete - Server missing intermediate certificates
  6. 6.System clock incorrect - Time skew causes validation failure

Step-by-Step Fix

Step 1: Check Certificate with OpenSSL

bash
openssl s_client -connect example.com:443 -showcerts

Step 2: Verify System Time

bash
date  # Linux/macOS
# or
Get-Date  # Windows PowerShell

Step 3: Check Certificate Details

bash
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

Step 4: Test URL in Browser

Open the URL in a browser and check for certificate warnings.

Solution 1: Update CA Certificates

```bash # macOS (after Homebrew Python installation) /Applications/Python\ 3.x/Install\ Certificates.command

# Or run this Python script import certifi import ssl print(ssl.get_default_verify_paths()) print(certifi.where()) ```

```bash # Linux (Ubuntu/Debian) sudo apt-get update && sudo apt-get install ca-certificates sudo update-ca-certificates

# Linux (RHEL/CentOS) sudo yum update ca-certificates sudo update-ca-trust ```

bash
# Update certifi package
pip install --upgrade certifi

Solution 2: Disable Verification (Development Only)

WARNING: Only use for development/testing, never in production

```python import requests

# Disable SSL verification (NOT RECOMMENDED for production) response = requests.get('https://example.com', verify=False)

# Suppress warnings import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) response = requests.get('https://example.com', verify=False) ```

Solution 3: Specify Custom CA Bundle

```python import requests

# Use custom CA bundle response = requests.get( 'https://example.com', verify='/path/to/ca-bundle.crt' )

# Or set environment variable import os os.environ['REQUESTS_CA_BUNDLE'] = '/path/to/ca-bundle.crt' os.environ['SSL_CERT_FILE'] = '/path/to/ca-bundle.crt' ```

Solution 4: Handle Self-Signed Certificates

```python import requests

# For self-signed certificate response = requests.get( 'https://self-signed.example.com', verify='/path/to/server.crt' )

# Or use certifi with custom cert import certifi import requests

# Add custom cert to certifi bundle # Then use normally response = requests.get('https://internal.example.com') ```

Solution 5: Corporate Proxy Certificates

```python import os import requests

# Set proxy certificate os.environ['REQUESTS_CA_BUNDLE'] = '/path/to/corporate-proxy-ca.pem' os.environ['HTTP_PROXY'] = 'http://proxy.company.com:8080' os.environ['HTTPS_PROXY'] = 'http://proxy.company.com:8080'

response = requests.get('https://example.com') ```

Solution 6: Fix urllib SSL Issues

```python import ssl import urllib.request

# Create SSL context ssl_context = ssl.create_default_context() ssl_context.load_verify_locations('/path/to/ca-bundle.crt')

# Use with urlopen with urllib.request.urlopen('https://example.com', context=ssl_context) as response: content = response.read() ```

Solution 7: Async Libraries (aiohttp)

```python import ssl import aiohttp

ssl_context = ssl.create_default_context() ssl_context.load_verify_locations('/path/to/ca-bundle.crt')

async with aiohttp.ClientSession() as session: async with session.get('https://example.com', ssl=ssl_context) as response: content = await response.text() ```

Solution 8: httpx Library

```python import httpx

# Custom verify response = httpx.get('https://example.com', verify='/path/to/ca-bundle.crt')

# Or with client with httpx.Client(verify='/path/to/ca-bundle.crt') as client: response = client.get('https://example.com') ```

Extract and Use Server Certificate

Extract Certificate from Server

bash
# Get certificate from server
openssl s_client -connect example.com:443 -showcerts </dev/null 2>/dev/null | openssl x509 -outform PEM > server.crt

Use Extracted Certificate

```python import requests

response = requests.get( 'https://example.com', verify='server.crt' ) ```

Combine Multiple Certificates

bash
# Create a custom CA bundle
cat /etc/ssl/certs/ca-certificates.crt > custom-ca-bundle.crt
cat corporate-proxy.pem >> custom-ca-bundle.crt
cat self-signed-server.crt >> custom-ca-bundle.crt
python
import os
os.environ['REQUESTS_CA_BUNDLE'] = '/path/to/custom-ca-bundle.crt'

Prevention

  1. 1.Keep certifi updated: pip install --upgrade certifi
  2. 2.Use proper certificates in production
  3. 3.Set up certificate rotation before expiry
  4. 4.Monitor certificate expiry with automation

```python # Check certificate expiry import ssl import socket from datetime import datetime

def check_cert_expiry(hostname, port=443): context = ssl.create_default_context() with socket.create_connection((hostname, port)) as sock: with context.wrap_socket(sock, server_hostname=hostname) as ssock: cert = ssock.getpeercert() expiry = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z') days_left = (expiry - datetime.now()).days return days_left

days = check_cert_expiry('example.com') print(f"Certificate expires in {days} days") ```

Verification

After fixing SSL certificate issues, verify that HTTPS requests work correctly:

```python import requests

def verify_ssl_connection(url): """Verify that SSL connection works correctly.""" try: response = requests.get(url, timeout=10) print(f"Successfully connected to {url}") print(f"Status code: {response.status_code}") return True except requests.exceptions.SSLError as e: print(f"SSL error still occurs: {e}") return False except Exception as e: print(f"Connection error: {e}") return False

# Test HTTPS connections verify_ssl_connection('https://www.google.com') verify_ssl_connection('https://api.github.com') ```

  • ConnectionRefusedError - Server not accepting connections
  • socket.timeout - Connection timed out
  • CertificateError - Hostname mismatch
  • [WordPress troubleshooting: Fix Django TypeError - Complete Troubles](fix-django-typeerror)
  • [WordPress troubleshooting: Fix async task exception not awaited Iss](async-task-exception-not-awaited)
  • [WordPress troubleshooting: Fix FastAPI AttributeError - Complete Tr](fix-fastapi-attributeerror)
  • [WordPress troubleshooting: Fix Flask AttributeError - Complete Trou](fix-flask-attributeerror)
  • [WordPress troubleshooting: Fix asyncio event loop closed rerun Issu](asyncio-event-loop-closed-rerun)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "How to Fix Python SSL Certificate Verify Failed", "description": "Solve Python SSL certificate verification errors. Fix self-signed certificates, corporate proxy issues, and HTTPS request failures in requests and urllib.", "url": "https://www.fixwikihub.com/fix-python-ssl-certificate-verify-failed", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-21T03:14:25.425Z", "dateModified": "2025-11-21T03:14:25.425Z" } </script>