Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
HTTPS

How to Fix an SSLError in Python Requests

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix an SSLError in Requests by identifying what failed before changing verification. A CERTIFICATE_VERIFY_FAILED message usually means the server certificate chain is not trusted. A hostname-mismatch message means the certificate identity does not match the host in your URL. A client-certificate error concerns mutual TLS and is configured separately. Keep HTTPS verification enabled for normal traffic; disabling it accepts untrusted certificates and can expose the connection to a man-in-the-middle attack.

Use the traceback, URL hostname, certificate chain, Python/Requests settings and network path (including corporate proxies or TLS inspection) to choose the remedy below.

1. Read the exact exception first

Capture the complete traceback rather than only the final line. Requests verifies server certificates by default and raises requests.exceptions.SSLError when it cannot verify one (Requests Advanced Usage).

CERTIFICATE_VERIFY_FAILED

This generally indicates that the issuer or chain is not in the CA bundle Requests is using, the certificate is expired, or a proxy has replaced the public certificate with one signed by an enterprise CA your Python process does not trust.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Hostname mismatch

The server (or an intercepting proxy) returned a certificate whose names do not include the hostname in your URL. Requests’ FAQ describes this as the certificate not matching the hostname it believes it is contacting (Requests FAQ).

TLS protocol or handshake errors

These can involve incompatible protocol or cipher settings, a middlebox, or a server that is not speaking TLS on the port. They are not fixed by adding an arbitrary CA file; inspect the endpoint and network path.

Client-certificate loading errors

If the traceback says a local certificate or private key cannot be loaded, the problem is your client credential, not the CA used to authenticate the server. The cert argument handles client authentication (Requests Developer Interface).

2. Confirm the URL and the certificate identity

  1. Print or inspect the exact URL passed to Requests, including the hostname and port. Avoid replacing a DNS name with an IP address unless the certificate explicitly contains that IP.
  2. Open the same HTTPS host in a browser or inspect it with an approved network diagnostic. Check the certificate’s Subject Alternative Name entries, validity dates and issuer.
  3. Ask whether your organization uses TLS inspection. Such a proxy deliberately substitutes its own certificate, so your Python process must trust the organization’s inspection CA.
  4. Do not download a CA file from an unverified connection and trust it blindly. Obtain the approved certificate or bundle through your server or network administrator.

3. Trust a private or enterprise CA safely

When the endpoint is intentionally signed by a private CA, point Requests at the approved PEM bundle. This preserves hostname and chain verification.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

One request

import requests

url = "https://internal.example.com/api/health"
r = requests.get(url, verify="/etc/ssl/company-ca-bundle.pem", timeout=30)
r.raise_for_status()
print(r.text)

verify accepts a path to a CA bundle (or, where supported by your setup, a directory prepared for certificate lookup). Use an absolute path while diagnosing so an unexpected working directory cannot select the wrong file.

Reuse a configured session

import requests

session = requests.Session()
session.verify = "/etc/ssl/company-ca-bundle.pem"
response = session.get("https://internal.example.com/api/health", timeout=30)
response.raise_for_status()

Configure the environment

For applications you cannot edit, set REQUESTS_CA_BUNDLE to the approved bundle. Requests also honors CURL_CA_BUNDLE as a fallback when REQUESTS_CA_BUNDLE is unset (Requests Advanced Usage).

# Linux/macOS
export REQUESTS_CA_BUNDLE=/etc/ssl/company-ca-bundle.pem
python app.py

# Windows PowerShell
$env:REQUESTS_CA_BUNDLE = "C:\certs\company-ca-bundle.pem"
python app.py

Make sure the bundle is readable by the account running the program and contains the issuing CA chain in PEM format. If the public endpoint should use the normal public trust store, remove an accidentally set custom variable rather than adding unrelated certificates.

4. Fix a hostname mismatch at the source

A hostname mismatch is an endpoint-identity problem, not a missing trust setting. Check these cases:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • The URL uses an alias, short host name or IP address absent from the certificate’s Subject Alternative Name.
  • DNS points to the wrong virtual host or load balancer.
  • A corporate proxy or TLS inspection device presents its own certificate for the requested host.
  • The server is misconfigured and needs a certificate containing the public hostname.

Use the correct DNS name in the URL, or have the server/network owner correct the certificate and virtual-host configuration. Adding the server certificate to a CA bundle does not make a name mismatch valid.

5. Configure mutual TLS (client certificates)

Some servers require your application to present a client certificate in addition to validating the server. Supply a combined PEM file or a certificate/key tuple:

import requests

# Combined certificate and private key
r = requests.get(
    "https://mtls.example.com/data",
    cert="/secure/client.pem",
    verify="/secure/private-ca-bundle.pem",
    timeout=30,
)
r.raise_for_status()

# Separate certificate and key
r = requests.get(
    "https://mtls.example.com/data",
    cert=("/secure/client.crt", "/secure/client.key"),
    verify="/secure/private-ca-bundle.pem",
    timeout=30,
)

The cert option authenticates your client; verify authenticates the server. Keep private-key permissions restricted. If loading fails, verify each path, PEM encoding, key passphrase handling and that the certificate matches the private key. Requests’ API documents both forms (Developer Interface).

6. Avoid the dangerous “fix”

requests.get("https://example.com", verify=False)

With verify=False, Requests accepts any certificate, ignores hostname mismatches and accepts expired certificates. The project explicitly warns that this makes applications vulnerable to man-in-the-middle attacks (Advanced Usage). Do not use it in production, and do not treat it as a permanent development solution. If you temporarily use it to prove that TLS verification is the failing layer, keep the test isolated, never send credentials, and replace it with the correct CA or server fix immediately.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

7. Prepared requests and missing environment settings

Most calls such as requests.get() automatically use environment configuration. A prepared-request flow can bypass those settings unless you merge them explicitly. Requests documents this distinction in its prepared-request example (Requests documentation PDF):

import requests

s = requests.Session()
req = requests.Request("GET", "https://internal.example.com/api")
prepared = s.prepare_request(req)

env = s.merge_environment_settings(
    prepared.url,
    proxies={},
    stream=None,
    verify=None,
    cert=None,
)
response = s.send(prepared, timeout=30, **env)
response.raise_for_status()

If REQUESTS_CA_BUNDLE is set, merging environment settings lets the session incorporate it. You can also pass an explicit verify path in merge_environment_settings when you want deterministic behavior.

8. A repeatable diagnostic script

Run this against a non-sensitive endpoint or an approved internal URL. It records the exception class without turning verification off.

import os
import ssl
import sys
import requests

url = "https://example.com"
print("Python:", sys.version)
print("Requests:", requests.__version__)
print("OpenSSL:", ssl.OPENSSL_VERSION)
print("REQUESTS_CA_BUNDLE:", os.environ.get("REQUESTS_CA_BUNDLE"))
print("CURL_CA_BUNDLE:", os.environ.get("CURL_CA_BUNDLE"))

try:
    response = requests.get(url, timeout=20)
    print("HTTP status:", response.status_code)
except requests.exceptions.SSLError as exc:
    print("TLS verification/handshake error:", exc)
except requests.exceptions.RequestException as exc:
    print("Other Requests error:", exc)

This does not prove which certificate a proxy supplied, but it makes interpreter, Requests and environment differences visible when comparing machines.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

9. Equivalent checks outside Python

cURL

cURL can test whether the same host succeeds with a supplied CA bundle. Keep verification enabled:

curl --fail --show-error --location 
  --cacert /etc/ssl/company-ca-bundle.pem 
  https://internal.example.com/api/health

A cURL failure does not automatically identify the Python problem, because the programs may use different trust stores or proxy variables. It is useful for separating server/network issues from Python configuration.

Node.js

For a Node client, add an approved CA with the HTTPS agent rather than disabling certificate checks:

import https from "node:https";
import fs from "node:fs";

const ca = fs.readFileSync("/etc/ssl/company-ca-bundle.pem");
https.get("https://internal.example.com/api/health", { ca }, res => {
  console.log(res.statusCode);
}).on("error", console.error);

These examples diagnose the same trust concept, but each runtime has its own environment variables and trust-store behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

10. Troubleshooting by symptom

Symptom Likely cause Correct action
unable to get local issuer certificate Missing public or private issuing CA Update the runtime trust store or pass the approved CA bundle with verify.
certificate verify failed: self signed certificate Intentionally private CA, or an untrusted interception certificate Obtain the authoritative CA through your organization and configure it; do not trust a random download.
hostname ... doesn't match URL, DNS, proxy or server certificate identity mismatch Use the certificate’s actual hostname or have the endpoint/proxy owner correct its certificate.
Works in a browser, fails in Python Different trust stores, proxy settings or environment variables Compare REQUESTS_CA_BUNDLE, proxy configuration, interpreter and Requests version.
Fails only with prepared requests Environment settings were not merged Use Session.merge_environment_settings() or pass the intended CA path explicitly.
Client key or certificate cannot be loaded Wrong path, permissions, format or mismatched key Validate files and permissions; configure cert separately from verify.
TLS handshake/protocol failure Incompatible server, proxy, protocol or cipher Check server and proxy TLS policy and supported versions; a CA change alone will not repair it.

11. Reliability, security and operational notes

  • Use a finite timeout on every request so a broken TLS path cannot hang a worker indefinitely.
  • Pin the CA-bundle path through deployment configuration and monitor certificate expiration through the service owner.
  • Do not log private keys, client certificates containing secrets or authorization headers while debugging.
  • When rotating an enterprise CA, deploy the new bundle before removing the old issuer, then verify from every runtime environment.
  • Keep Python, Requests and the operating system’s trust material maintained. The Python ssl module documentation describes the TLS wrapper and context behavior (Python 3.14.7 ssl documentation).

Or skip the browser setup

If your goal is to capture a page rather than debug its TLS stack, ScreenshotNeo provides a website screenshot API. One GET request returns PNG, JPEG, WebP or PDF. Before capture it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

Using the API requires no browser setup:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for all options, including custom headers, cookies, user agents, authorization, waiting conditions and PDF settings. A free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Frequently asked questions

Does installing certifi always fix Requests SSL errors?

No. It can provide a current public CA bundle, but it cannot correct a hostname mismatch, a broken server chain, a TLS protocol failure or an enterprise CA that is absent from the bundle.

Should I add the website’s leaf certificate to verify?

Normally no. Configure the authoritative CA bundle that issued the server certificate. A leaf certificate is difficult to rotate and does not solve a name mismatch.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Is a self-signed certificate automatically unsafe?

It is untrusted by default, not automatically malicious. In a controlled private service, trust its issuing CA through an approved distribution channel and keep hostname verification enabled.

Frequently Asked Questions

Can a proxy cause an SSLError even when the public website is valid?

Yes. TLS inspection can replace the public certificate with one signed by an enterprise CA. Your Python process must trust that organization’s approved CA bundle, and the URL hostname must still match.

What is the difference between verify and cert in Requests?

verify validates the server certificate using a CA bundle. cert supplies your client certificate and key for mutual TLS; they solve different authentication steps.

Why does the same URL work with requests.get() but fail in a prepared-request flow?

Prepared requests may not automatically incorporate environment settings such as REQUESTS_CA_BUNDLE. Merge the session’s environment settings before sending, or provide the CA path explicitly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.