Diagnose TLS failures
Diagnose a hostname mismatch
Compare the requested name with certificate SAN entries and repair the identity instead of disabling checks.
10 minute lesson
A trusted certificate can still be wrong for the requested hostname. Chain verification and name verification are two separate checks: the first asks “did a trusted CA sign this?”, the second asks “is this certificate for the name I typed?”. A certificate for app.lab.test is genuinely valid — for app.lab.test. Ask for any other name and the identity check must fail.
Let’s force a mismatch against the local server. Our lab certificate includes DNS:localhost in its SAN, so pick a name it does not cover:
curl --cacert lab-ca.crt https://127.0.0.1:8443/
# curl: (60) SSL: no alternative certificate subject name matches target host name '127.0.0.1'
Read the exact error. curl trusted the chain — --cacert handled that — and failed only on the name comparison. Depending on your curl version the wording mentions the subject name or the alternative names, but the shape is the same: the name you requested, and the statement that no certificate name matched it.
Now inspect what names the leaf actually covers:
openssl s_client -connect 127.0.0.1:8443 </dev/null 2>/dev/null | openssl x509 -noout -ext subjectAltName
# X509v3 Subject Alternative Name:
# DNS:app.lab.test, DNS:localhost
This pipe grabs the leaf from the live server and decodes its SAN. Diagnosis is now a comparison: requested 127.0.0.1, offered app.lab.test and localhost. No overlap, so the failure is correct.
From there you have exactly two honest fixes. Fix the requested hostname — connect using a name the certificate covers, such as https://localhost:8443/ in our lab. Or fix the certificate issuance policy — reissue with a SAN that includes the name clients really use. In production the second is usually right: clients use the name they use, and the certificate must match reality.
In real systems this error usually means a URL pointing at an internal IP, a certificate that lists www.example.org but not example.org, or a service migrated to a new name with the old certificate still deployed.
Do not solve a name mismatch with --insecure; that removes the identity check you need. It does not skip just this error — it accepts any certificate from anyone, which is precisely the attack TLS names exist to stop.
Lesson completed