An SSLError, requests.exceptions.SSLError, or SSLCertVerificationError usually means Python requests could not verify the server's SSL certificate. This can happen if the server uses a self-signed certificate, a private Certificate Authority (CA), an expired certificate, or a certificate that is not trusted by your system.
Requests validates every HTTPS certificate against the certifi CA bundle by default, so a certificate it cannot trust fails the request instead of returning a response:
requests.exceptions.SSLError: HTTPSConnectionPool(host='self-signed.badssl.com', port=443):
Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1,
'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate')))
The verify parameter controls that check, so the fix is either to give requests a certificate it can trust or to turn the check off.
Fix 1: Use a Trusted Certificate
If you have the website's CA certificate or internal CA bundle, save the .pem file and pass its path with the verify parameter. This lets requests verify the server's certificate while keeping the HTTPS connection secure.
Here is some sample code for providing a custom .pem certificate file to requests:
import requests
custom_certificate_path = "./certificates/custom-certificate.pem"
response = requests.get(
"https://your-server.example/",
verify=custom_certificate_path
)
print(response.status_code)
Replace the URL with your server and the path with the real location of your certificate. A successful request prints the server's status code, such as 200. If the file is not there, requests raises OSError: Could not find a suitable TLS CA certificate bundle, invalid path rather than an SSLError, so check the path first when that shows up.
verify also accepts a directory of certificates, provided the directory has been processed with the OpenSSL c_rehash utility. To reuse the same bundle everywhere without repeating the argument, set session.verify on a requests.Session object, or export the REQUESTS_CA_BUNDLE environment variable.
Fix 2: Disable SSL Verification
For local development or temporary testing, you can bypass SSL verification by passing verify=False. This can resolve a certificate verify failed error, but it should not be used in production or with sensitive data.
Here is some sample code that disables SSL verification:
import requests
response = requests.get("https://self-signed.badssl.com/", verify=False)
print(response.status_code)
The request goes through and prints 200, even though the certificate is self-signed. urllib3 also prints an InsecureRequestWarning on every such call to flag that the connection is unverified. You can silence it with urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning), but the warning is worth leaving in place as a reminder.
Warning: Setting verify=False tells Python to skip SSL certificate verification. It might get your request working, but it also removes an important security check. The hostname check goes with it, so the connection is no longer protected against man-in-the-middle attacks. Use it only for local development or temporary testing, and avoid it in production or when sending sensitive data.