Introduction
Modern SSL certificates use Subject Alternative Names (SANs) instead of the Common Name (CN) to specify which domains the certificate covers. If a user visits www.example.com but the certificate only lists example.com in its SANs (without www.example.com), the browser shows a certificate name mismatch error. This is one of the most common SSL errors on the web, affecting both production sites and staging environments.
Symptoms
- Browser shows
Your connection is not privatewithNET::ERR_CERT_COMMON_NAME_INVALID curl -vI https://www.example.comshowsSSL: no alternative certificate subject name matched- Certificate details show
SAN: example.combut you are accessingwww.example.com openssl s_clientshowsVerify return code: 62 (Hostname mismatch)- API clients fail with
certificate verify failed: Hostname mismatch
Common Causes
- Certificate issued for bare domain only, missing www variant
- Wildcard certificate
*.example.comdoes not coverexample.com(bare domain) - SAN not properly configured in the CSR (Certificate Signing Request)
- Subdomain added after certificate issuance without reissuing
- Let's Encrypt certificate not requested with all domain variants
Step-by-Step Fix
- 1.Check the certificate's current SANs:
- 2.```bash
- 3.openssl s_client -connect www.example.com:443 -servername www.example.com </dev/null 2>/dev/null | \
- 4.openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
- 5.# Output: DNS:example.com (missing www.example.com)
- 6.
` - 7.Generate a new CSR with all required SANs:
- 8.```bash
- 9.openssl req -new -newkey rsa:2048 -nodes \
- 10.-keyout example.com.key \
- 11.-out example.com.csr \
- 12.-subj "/CN=example.com" \
- 13.-addext "subjectAltName=DNS:example.com,DNS:www.example.com"
- 14.
` - 15.For Let's Encrypt (certbot), request all domains at once:
- 16.```bash
- 17.sudo certbot certonly --webroot \
- 18.-w /var/www/html -d example.com -d www.example.com \
- 19.--agree-tos --email admin@example.com
- 20.
` - 21.For a broader solution, use a wildcard certificate:
- 22.```bash
- 23.# Wildcard covers all subdomains: *.example.com
- 24.# But NOT the bare domain example.com - include both:
- 25.sudo certbot certonly --manual --preferred-challenges dns \
- 26.-d example.com -d "*.example.com"
- 27.
` - 28.Verify the new certificate covers all domains:
- 29.```bash
- 30.openssl x509 -in new-cert.pem -noout -text | grep -A1 "Subject Alternative Name"
- 31.# Should show: DNS:example.com, DNS:www.example.com
- 32.
` - 33.Configure the web server to redirect www to non-www (or vice versa):
- 34.```nginx
- 35.server {
- 36.listen 80;
- 37.server_name www.example.com;
- 38.return 301 https://example.com$request_uri;
- 39.}
- 40.
`
Prevention
- Always include both
example.comandwww.example.comin certificate SANs - Use wildcard certificates (
*.domain.com) for environments with many subdomains - Automate certificate management with tools that handle SAN configuration
- Test new certificates against all domain variants before deploying
- Implement HTTP-to-HTTPS redirects that cover all domain variants