# 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.

```text
Hostname/IP does not match certificate's altnames
```

## Use 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
1. Print the cert's SAN list:
```
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -ext subjectAltName
```
Expected: a list like DNS:example.com, DNS:www.example.com. Check whether your hostname is in it.

2. 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.

3. 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.

4. Verify from the client side with strict checking:
```
curl -s -o /dev/null -w "%{http_code}" https://example.com
```
Expected: 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
