Python Requests Throwing Sslerror

Better Stack Team
Updated on October 7, 2024

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.

Got an article suggestion? Let us know
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

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 us
Writer of the month
Marin Bezhanov
Marin is a software engineer and architect with a broad range of experience working...
Build 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.com

or submit a pull request and help us build better products for everyone.

See the full list of amazing projects on github