← Debugging Guides

阅读中文版本

requests — SSLError: certificate verify failed (hostname mismatch)

Diagnose certificate verify failures by separating hostname mismatch, missing CA trust and expired certificates.

intermediatedebuggingpythontls

Symptoms

  • SSLError: certificate verify failed: unable to get local issuer certificate
  • SSLError mentioning hostname mismatch or self-signed certificate
  • curl succeeds with -k but fails without it
  • The error appears only for some hosts or after a network change

Possible causes

  • The server certificate does not match the requested hostname
  • The issuing CA is not in the client trust store
  • The certificate chain is incomplete so verification cannot build a path
  • The certificate is expired or the system clock is wrong

Diagnosis steps

Inspect the certificate chain

openssl s_client -connect host:443 -servername host -showcerts

Interpretation

The output shows the presented chain, the subject alternative names and the validity dates, revealing mismatch, incomplete chain or expiry.

Compare hostname with subject alternative names

openssl s_client -connect host:443 -servername host 2>/dev/null | openssl x509 -noout -ext subjectAltName

Interpretation

If the requested name is absent from the SAN list, verification fails regardless of trust.

Check the client trust store

python -c "import certifi; print(certifi.where())"

Interpretation

A missing or outdated CA bundle explains unable to get local issuer certificate even when the chain is valid.

Root cause

Certificate verification failed because the presented certificate did not match the hostname, was not trusted by the client CA store, or the chain was incomplete or invalid.

Fix

Request the correct hostname, install or update the CA bundle so the issuer is trusted, and fix the server to present a complete chain. Never disable verification as a permanent fix.

Verify the fix

Repeat the request and confirm it succeeds without verification errors, then recheck the chain to confirm the issuer and hostname match.

Symptom walkthrough

A request raises SSLError with certificate verify failed, sometimes adding unable to get local issuer certificate or hostname mismatch. The distinction matters: message text varies with whether the problem is a missing CA, an incomplete chain, a name mismatch or an expired certificate. Passing verify=False or curl -k makes it work, which confirms the failure is verification rather than connectivity.

Fix in practice

Diagnose which failure mode applies by inspecting the chain and SAN list, then fix the specific cause: use the correct hostname, install or refresh the CA bundle, or correct the server chain. Disabling verification is not a fix, because it removes the protection that detected the problem.

Verification

Rerun the request and confirm it succeeds with verification enabled, then re-inspect the chain to confirm the issuer is trusted and the hostname matches the certificate.

Diagnostic commands

Check the behavior with commands like these:

openssl s_client -connect host:443 -servername host -showcerts
openssl s_client -connect host:443 -servername host 2>/dev/null | openssl x509 -noout -ext subjectAltName
python -c "import certifi; print(certifi.where())"