TLS/SSL certificate or handshake error
Production Risk
CRITICAL if bypassed; always fix the certificate rather than disabling verification.
Raised by the ssl module when a TLS/SSL error occurs — certificate verification failure, handshake error, or protocol mismatch. The most common cause is an untrusted or expired certificate.
- 1Server certificate is self-signed or from an untrusted CA
- 2Certificate has expired
- 3Hostname does not match the certificate CN/SAN
- 4TLS protocol version mismatch (e.g., server requires TLS 1.3, client only has 1.2)
Connecting to a server with an expired or self-signed certificate.
import ssl
import urllib.request
urllib.request.urlopen('https://expired.badssl.com/')expected output
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired
Fix 1
Fix the server certificate
WHEN The certificate is expired or invalid
# Check certificate details openssl s_client -connect hostname:443 </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer # Renew with Let's Encrypt: certbot renew
Why this works
Certificates must be valid, not expired, and match the hostname. Let's Encrypt provides free 90-day certificates.
Fix 2
Use a custom CA bundle for internal services
WHEN Connecting to internal services with private CAs
import ssl
import urllib.request
ctx = ssl.create_default_context(cafile='/path/to/internal-ca.pem')
urllib.request.urlopen('https://internal-service/', context=ctx)Why this works
Providing the internal CA certificate allows verification without disabling SSL.
import urllib.request
urllib.request.urlopen("https://expired.badssl.com/") # SSLCertVerificationErrorimport ssl, urllib.request
try:
response = urllib.request.urlopen(url)
except ssl.SSLError as e:
print(f"SSL error: {e}")import ssl, urllib.request ctx = ssl.create_default_context(cafile="/path/to/ca.pem") response = urllib.request.urlopen(url, context=ctx)
✕ Disable SSL verification with verify=False or ssl.CERT_NONE
This makes MITM attacks trivial; attackers can intercept all traffic. Only use in isolated test environments, never production.
Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev