Hostname/IP does not match certificate's altnames
A step-by-step skill for fixing Node's 'Hostname/IP does not match certificate's altnames' TLS error: reading the cert's SAN list with openssl, finding the exact name mismatch, and fixing the URL or reissuing the cert. Use when HTTPS calls fail on hostname verification in Node, Python, or curl. Triggers: 'does not match certificate's altnames', 'hostname mismatch', 'SAN mismatch'. Not for: expired certs, untrusted CAs, or incomplete chains.
Hostname/IP does not match certificate's altnames
TL;DR
The certificate's Subject Alternative Names don't include the hostname you're connecting to. Either connect using a name that's actually on the cert, or reissue the cert with the right SANs. Don't disable hostname verification to make it shut up.
Hostname/IP does not match certificate's altnamesUse this when
- Node, Python requests, or curl fail a TLS handshake with this exact message
- A service works in the browser but fails from code
- You just added a new subdomain, moved to an IP-based URL, or changed DNS
- Staging and production use different hostnames with one cert
Not for this skill when
- The error is about an expired certificate (renew it)
- The error is about an untrusted or self-signed CA (fix trust, not names)
- The error is "unable to verify the first certificate" (incomplete chain, different fix)
Steps
- Print the cert's SAN list:
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -ext subjectAltNameExpected: a list like DNS:example.com, DNS:www.example.com. Check whether your hostname is in it.
- Compare with the URL your code actually calls. The classic mismatch: code calls the bare domain but the cert only lists www, or calls an IP address while the cert lists DNS names.
Expected: you can point at the exact mismatch.
- If the hostname is wrong, fix the URL or DNS to use a name on the cert. If the cert is wrong, reissue it with every name the service answers on, including both apex and www.
Expected: the SAN list covers every hostname clients use.
- Verify from the client side with strict checking:
curl -s -o /dev/null -w "%{http_code}" https://example.comExpected: prints 200 with no TLS error. In Python, requests.get("https://example.com") should return without an SSLError.
Variant: IP address in the URL
Certs need an IP-type SAN entry for IP literals, not a DNS entry. Better yet, stop calling the IP and use a DNS name that's on the cert.
Variant: Kubernetes service DNS names
Include the cluster-local names on the cert, or have in-cluster clients use the external name. The short service name and the fully qualified name are different SANs.
Variant: self-signed certificate sibling error
That's a trust problem, not a name problem. Different fix: add the CA to the trust store instead of editing SANs.
Why this happens
TLS clients check that the name they asked for appears in the cert's SAN list. This stops a valid cert for one site being presented for another. Mismatches almost always come from connecting via a name nobody put on the cert: an IP, a new subdomain, or an internal alias.
Edge cases and pitfalls
- Wildcard certs cover one level only: *.example.com does not cover a.b.example.com.
- After reissue, clients may cache the old cert; restart them or wait out the cache before declaring victory.
- In dev, add the name to your hosts file and mint a local cert for it rather than disabling verification.
- Load balancers sometimes serve a default cert when SNI doesn't match; check the SNI name your client sends, not just the URL.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_VR7qtENHFurTaxOqNJekLA