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 private with NET::ERR_CERT_COMMON_NAME_INVALID
  • curl -vI https://www.example.com shows SSL: no alternative certificate subject name matched
  • Certificate details show SAN: example.com but you are accessing www.example.com
  • openssl s_client shows Verify 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.com does not cover example.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. 1.Check the certificate's current SANs:
  2. 2.```bash
  3. 3.openssl s_client -connect www.example.com:443 -servername www.example.com </dev/null 2>/dev/null | \
  4. 4.openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
  5. 5.# Output: DNS:example.com (missing www.example.com)
  6. 6.`
  7. 7.Generate a new CSR with all required SANs:
  8. 8.```bash
  9. 9.openssl req -new -newkey rsa:2048 -nodes \
  10. 10.-keyout example.com.key \
  11. 11.-out example.com.csr \
  12. 12.-subj "/CN=example.com" \
  13. 13.-addext "subjectAltName=DNS:example.com,DNS:www.example.com"
  14. 14.`
  15. 15.For Let's Encrypt (certbot), request all domains at once:
  16. 16.```bash
  17. 17.sudo certbot certonly --webroot \
  18. 18.-w /var/www/html -d example.com -d www.example.com \
  19. 19.--agree-tos --email admin@example.com
  20. 20.`
  21. 21.For a broader solution, use a wildcard certificate:
  22. 22.```bash
  23. 23.# Wildcard covers all subdomains: *.example.com
  24. 24.# But NOT the bare domain example.com - include both:
  25. 25.sudo certbot certonly --manual --preferred-challenges dns \
  26. 26.-d example.com -d "*.example.com"
  27. 27.`
  28. 28.Verify the new certificate covers all domains:
  29. 29.```bash
  30. 30.openssl x509 -in new-cert.pem -noout -text | grep -A1 "Subject Alternative Name"
  31. 31.# Should show: DNS:example.com, DNS:www.example.com
  32. 32.`
  33. 33.Configure the web server to redirect www to non-www (or vice versa):
  34. 34.```nginx
  35. 35.server {
  36. 36.listen 80;
  37. 37.server_name www.example.com;
  38. 38.return 301 https://example.com$request_uri;
  39. 39.}
  40. 40.`

Prevention

  • Always include both example.com and www.example.com in 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