When Python's requests
library throws an SSLError
, it typically indicates that the SSL/TLS handshake failed when trying to establish a secure connection to a remote server. This can happen for several reasons, including certificate verification issues, outdated SSL libraries, or problems with the server's SSL configuration. Here are some common causes and how to resolve them:
1. Certificate Verification Failure
The most common reason for an SSLError
in requests
is a failure to verify the SSL certificate of the remote server.
Solution: Disable SSL Verification (Temporary Fix)
You can bypass SSL certificate verification by setting the verify
parameter to False
. However, this should only be used for testing purposes as it exposes your connection to potential security risks.
import requests
response = requests.get('<https://example.com>', verify=False)
print(response.content)
Warning: Disabling SSL verification is not recommended for production code due to security concerns.
Solution: Provide a CA Bundle
If you want to maintain security and properly verify certificates, you can provide a custom CA bundle. You can use the certifi
package to handle SSL verification:
pip install certifi
Then use it in your code:
import requests
import certifi
response = requests.get('<https://example.com>', verify=certifi.where())
print(response.content)
2. Outdated or Missing CA Certificates
If the CA certificates on your system are outdated, requests
may not be able to validate the server's certificate.
Solution: Update CA Certificates
- On Windows: Ensure that your system's CA certificates are up-to-date. You can also use the
certifi
package as mentioned above. On Linux/macOS: Update your system's CA certificates using your package manager:
Debian/Ubuntu:
sudo apt-get install --reinstall ca-certificates
Fedora/CentOS/RHEL:
sudo yum reinstall ca-certificates
macOS (Homebrew):
brew install openssl
3. Server-Side Issues
Sometimes, the issue lies with the server's SSL/TLS configuration, such as using an unsupported or outdated protocol.
Solution: Use a Different SSL Protocol
You can force requests
to use a different SSL version by using the urllib3
library, which requests
is built upon.
import requests
from urllib3 import PoolManager
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
class SSLAdapter(HTTPAdapter):
def __init__(self, ssl_version=None, **kwargs):
self.ssl_version = ssl_version
super(SSLAdapter, self).__init__(**kwargs)
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ssl_version=self.ssl_version)
kwargs['ssl_context'] = context
return super(SSLAdapter, self).init_poolmanager(*args, **kwargs)
session = requests.Session()
adapter = SSLAdapter()
session.mount('https://', adapter)
response = session.get('<https://example.com>')
print(response.content)
You can specify the ssl_version
by passing it to create_urllib3_context
.
4. Expired or Revoked Certificates
If the server's certificate has expired or been revoked, requests
will throw an SSLError
.
Solution: Contact the Server Administrator
If the server's certificate is indeed expired or revoked, the best course of action is to contact the server administrator to have it renewed or replaced.
5. System Time Incorrect
SSL/TLS certificates have a validity period. If your system clock is incorrect, the certificate might appear invalid.
Solution: Sync System Time
Ensure your system clock is set correctly:
- Windows: Adjust the date and time settings from the Control Panel.
- Linux/macOS: Use
ntpdate
or another time synchronization tool.
sudo ntpdate -u time.nist.gov
6. Intermediary Issues (e.g., Proxy or Firewall)
A proxy or firewall might be intercepting the SSL traffic and causing the error.
Solution: Bypass or Configure the Proxy/Firewall
- Check if your system uses a proxy or firewall that intercepts SSL.
- Configure
requests
to use the correct proxy settings, or bypass the proxy if possible.
proxies = {
"http": "<http://proxy.example.com:8080>",
"https": "<https://proxy.example.com:8080>",
}
response = requests.get('<https://example.com>', proxies=proxies)
print(response.content)
Summary
SSLError
in Python's requests
library typically arises from SSL/TLS handshake failures due to certificate verification issues, outdated libraries, or server misconfigurations. You can temporarily bypass the error by disabling SSL verification, but the recommended approach is to use proper CA certificates or update your system's SSL configuration. Debugging the issue by checking certificate details, system time, and any intermediary network devices can also help in resolving the problem.
Make your mark
Join the writer's program
Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.
Write for usBuild on top of Better Stack
Write a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.
community@betterstack.comor submit a pull request and help us build better products for everyone.
See the full list of amazing projects on github