Keywords: HTTPS | SSL Certificate Verification | Python requests | CERTIFICATE_VERIFY_FAILED | Development Environment Configuration
Abstract: This technical article provides an in-depth analysis of the CERTIFICATE_VERIFY_FAILED error that occurs during HTTPS requests using Python's requests library. It examines the root causes including system certificate store issues and self-signed certificate validation failures. The article presents two primary solutions with detailed code examples: specifying custom CA certificate files and disabling SSL verification. Drawing from real-world Django development scenarios, it discusses best practices for handling certificate verification in both development and production environments, offering comprehensive guidance for developers to understand SSL certificate validation mechanisms and effectively resolve related issues.
SSL Certificate Validation Mechanism Overview
HTTPS protocol ensures secure communication through SSL/TLS encryption, where certificate validation serves as the core security component. When a client initiates an HTTPS request, the system validates the server certificate's legitimacy, including certificate chain integrity, certificate authority trustworthiness, and validity period.
Common Error Scenarios Analysis
In Python development environments, several certificate verification failure scenarios may occur when using the requests library for HTTPS requests:
System Certificate Store Issues: Some operating systems (such as Windows 7) may lack updated root certificates or have incomplete certificate chains, preventing validation of well-known website certificates.
import requests
response = requests.get('https://google.com') # May raise SSLError
Self-Signed Certificate Environments: When using self-signed certificates or certificates issued by internal CAs in development environments, the default certificate validation mechanism rejects these non-publicly trusted certificates.
Detailed Solution Approaches
Method 1: Specifying Custom CA Certificates
Use the verify parameter to specify a custom certificate file path, directing the requests library to use specific CA certificates for validation:
import requests
response = requests.get('https://google.com', verify='/path/to/certfile.pem')
This approach is suitable for enterprise intranet environments or development scenarios using self-signed certificates, maintaining security validation while resolving certificate trust issues.
Method 2: Disabling SSL Verification
In development or testing environments, SSL certificate verification can be temporarily disabled:
import requests
response = requests.get('https://google.com', verify=False)
Important Note: This method reduces security and should only be used in non-production environments. Disabling certificate verification in production exposes the system to man-in-the-middle attack risks.
Practical Development Scenario Applications
In Django application development, similar certificate verification issues may arise when communicating with other HTTPS services (such as Keycloak authentication services). This is particularly common in development environments where reverse proxies (like Traefik) manage certificates.
For third-party library code that cannot be directly modified (such as Django allauth plugins), certificate verification behavior can be configured through environment variables or custom Session objects:
import requests
import os
# Configuration via environment variables
os.environ['REQUESTS_CA_BUNDLE'] = '/path/to/certfile.pem'
# Or using custom Session
session = requests.Session()
session.verify = '/path/to/certfile.pem'
response = session.get('https://internal-service.example.com')
Development and Production Environment Best Practices
Development Environment: Recommended to use tools like mkcert to generate locally trusted development certificates, or appropriately use the verify=False option. Ensure development teams understand related security risks.
Production Environment: Must use valid SSL certificates, preferably obtained from authoritative CAs (such as Let's Encrypt), and ensure applications are correctly configured for certificate verification. Using reverse proxies like nginx, haproxy, or Traefik for SSL termination is the recommended architecture.
Certificate Management Recommendations
For applications requiring handling of multiple certificate environments, consider:
- Maintaining separate certificate configurations for development, testing, and production environments
- Using configuration files or environment variables to manage certificate paths
- Regularly updating system root certificate stores
- Monitoring certificate expiration and establishing automatic renewal mechanisms
Through proper certificate management strategies, applications can ensure secure and reliable HTTPS communication across different environments while avoiding connection failures caused by certificate issues.