How to Fix Python Requests SSLError?
The Python requests
library is widely used for making HTTP requests simply and elegantly. However, when working with SSL (Secure Sockets Layer) connections, users may occasionally encounter an SSLError
. This error typically arises due to issues with SSL certificates, which are crucial for establishing a secure connection between a client and a server. Understanding the causes of this error and how to resolve it is essential for developers to maintain secure and reliable communication in their applications.
In this article, we'll explore why SSLError
occurs in Python's requests
library and provide various methods to fix it.
Why Does SSLError
Occur?
SSLError
in Python's requests
library typically occurs due to issues related to SSL certificates. Here are some common reasons why this error might be triggered:
1. Expired SSL Certificate: If the server's SSL certificate has expired, the requests
library will raise an SSLError
. This often happens when trying to access outdated or poorly maintained websites.
import requests
url = "https://expired.badssl.com/"
try:
response = requests.get(url)
print(response.content)
except requests.exceptions.SSLError as e:
print("SSLError:", e)
Output

2. Self-Signed Certificates: Self-signed certificates are not trusted by default because they are not signed by a recognized certificate authority. As a result, requests to servers using self-signed certificates can cause an SSLError
.
import requests
url = "https://self-signed.badssl.com/"
try:
response = requests.get(url)
print(response.content)
except requests.exceptions.SSLError as e:
print("SSLError:", e)
Output

3. Outdated SSL Library: An outdated version of the SSL library (OpenSSL, for example) on our system may not support the SSL/TLS version used by the server, leading to an SSLError
.
import requests
url = "https://tls-v1-0.badssl.com:1010/"
try:
response = requests.get(url)
print(response.content)
except requests.exceptions.SSLError as e:
print("SSLError:", e)
Output

4. Untrusted Certificate Authority (CA): If the SSL certificate is signed by an untrusted or unknown certificate authority, the requests
library will not trust the certificate, leading to an SSLError
.
5. Mismatched SSL/TLS Protocol Versions: If the server is using a specific version of SSL/TLS that is not supported by the requests
library or the underlying SSL library, an SSLError
may occur.
How to Fix Python Requests SSLError
There are several ways to resolve the SSLError
depending on the root cause. Here are some common solutions:
1. Verify and Trust the Certificate
If the error occurs because the certificate is signed by an untrusted CA, we can manually add the CA's certificate to our system's trusted store or provide the path to the certificate file in our request.
This method ensures that the requests
library trusts the certificate authority that signed the SSL certificate.
import requests
url = "https://your-custom-url.com/"
cert_path = "/path/to/your/custom-certificate.crt"
response = requests.get(url, verify=cert_path)
print(response.content)
Output
The output would be similar to the one shown above, displaying the HTML content of the requested page.
<!DOCTYPE html>
<html>
<head>
<title>self-signed.badssl.com</title>
...
</head>
<body>
<h1>self-signed.badssl.com</h1>
...
</body>
</html>
If the certificate path is invalid or there are issues with the certificate, we would get SSLError.
2. Ignoring SSL Warnings
We can disable SSL verification by setting verify=False
in our requests
call. However, this is not a recommended approach to interact with servers as it exposes our application to potential security risks like man-in-the-middle (MITM) attacks.
With the latest versions of libraries having some extra security checks, this method may not work. Also, we should use this method only in development environment when it is necessary.
import requests
response = requests.get('https://example.com', verify=False)
print(response.content)
Output
We typically see the HTML content of the page:
<!DOCTYPE html>
<html>
<head>
<title>self-signed.badssl.com</title>
...
</head>
<body>
<h1>self-signed.badssl.com</h1>
...
</body>
</html>
We generally get this type of warnings with the above approach:
InsecureRequestWarning: Unverified HTTPS request is being made to host 'self-signed.badssl.com'.
Adding certificate verification is strongly advised
3. Update the certifi Package
The requests library relies on the certifi package to verify SSL certificates. If we get SSLError due to outdated root certificates, updating the certifi package may resolve the issue.
pip install --upgrade certifi
import requests
import certifi
url = "https://example.com/"
response = requests.get(url, verify=certifi.where())
print(response.content)
Output
If everything works fine, we could see the HTML content of the requested page:
<!DOCTYPE html>
<html>
<head>
<title>Example Domain</title>
...
</head>
<body>
<h1>Example Domain</h1>
...
</body>
</html>
This method usually resolves issues when connecting to sites with valid but updated SSL certificates.
4. Upgrading Python and OpenSSL
If our issue is related to outdated SSL/TLS protocol versions, upgrading Python and OpenSSL can help resolve the problem. Many older versions of Python do not support modern TLS versions.
Upgrade OpenSSL on Window:
pip install --upgrade openssl
On Linux:
sudo apt install --only-upgrade openssl
After upgrading Python and OpenSSL, our requests to older servers should work without the SSLError. The output would be similar to the previous examples, showing the HTML content of the page.
Conclusion
SSLError
in Python's requests
library is a common issue, especially when dealing with SSL certificates and secure connections. Understanding the root cause of the error and applying the appropriate fix is crucial for maintaining secure and reliable connections in our application. Whether it's updating SSL certificates, trusting a new CA, or upgrading our SSL library, the solutions discussed here help us resolve most SSLError
cases. Always prioritize security by avoiding quick fixes like disabling SSL verification unless absolutely necessary.