TLS Certificate Errors: Trust, Hostname and Expiry

Replacing a CA bundle immediately after a TLS error can miss a hostname mismatch or expiry. Separate the presented certificate, the requested hostname, the client’s trusted authorities and the verification time. Also record whether failure occurred before any HTTP response.

One certificate, different failure conditions

A temporary self-signed certificate had a one-day lifetime and the SAN good.test. Trusting it only through that command’s CAfile and checking good.test returned exit code 0. Checking wrong.test produced error 62; excluding the default trust stores without supplying a CA produced error 18; setting verification time two days ahead produced error 10. The system clock and production trust stores were unchanged.

openssl verify -CAfile cert.pem -verify_hostname good.test cert.pem
openssl verify -CAfile cert.pem -verify_hostname wrong.test cert.pem

These commands are an offline comparison using your own test cert.pem. Trust, identity and time are separate inputs in the OpenSSL verification options. Do not equate a missing intermediate on a live server with an untrusted self-signed certificate.

Match the connection identity and SNI on a live server

If connecting by IP differs from connecting by domain, also inspect virtual-host selection. Do not hide the need for a correctly named certificate with verify=False or curl -k. If the chain works elsewhere but one Python environment fails, compare that interpreter’s CA paths and library settings. Printing default SSL paths does not prove that a library such as Requests uses that same bundle.

After a correction, repeat the original client, hostname and network path with verification enabled. Record TLS success separately from HTTP authorization errors. This self-signed fixture does not validate a live certificate deployment or a full-chain repair.