When a browser connects to an HTTPS website, it checks the certificate to verify the server is who it claims to be. The specific mechanism for this check changed permanently in 2017: browsers now use the Subject Alternative Name (SAN) extension exclusively for hostname matching and completely ignore the Common Name (CN) field for this purpose.
This change has a precise technical basis and a specific consequence: any certificate without a SAN entry for the connecting hostname fails validation regardless of what the Common Name says. The error in Chrome is ERR_CERT_COMMON_NAME_INVALID, which has confused many server operators who assumed that setting the CN correctly was sufficient.
This guide explains the SAN extension’s role in certificate validation, the rules browsers follow when checking it, all the SAN types and their specific matching semantics, and the common mistakes that result in SAN-related certificate errors.
What the Subject Alternative Name Extension Is
The Subject Alternative Name extension is defined in RFC 5280, Section 4.2.1.6. It is an X.509 certificate extension that lists one or more identities the certificate is valid for. Unlike the Subject field’s Common Name, which is an untyped string, each SAN entry has an explicit type that determines how it is matched.
The extension was introduced because the Common Name was designed for human-readable identity (a company name, a person’s name) and was repurposed in early web certificates to contain a domain name. This repurposing created ambiguity: was the CN a domain name or an organization name? The SAN extension provides a typed, unambiguous alternative where a dNSName entry is explicitly a domain name intended for hostname validation.
RFC 2818 (the HTTPS specification, published May 2000) stated that if a SAN extension is present, the CN must not be used for hostname matching. This was a recommendation for two decades before it became a strict enforcement in 2017.
The Critical Extension Rule: SAN Present Means CN Is Ignored
RFC 5280 defines a specific rule for the SAN extension that has important implications: if a certificate contains a SAN extension at all, clients MUST use it for identity matching and MUST ignore the Common Name entirely.
The implications:
- Certificate has SAN with correct hostname: validation passes. CN is irrelevant.
- Certificate has SAN but with wrong or missing hostname: validation fails. CN is still irrelevant, even if CN matches.
- Certificate has no SAN extension at all: some older clients fall back to CN matching. Current browsers do not fall back; they require SAN.
- Certificate has an empty SAN extension (present but listing no entries): client is forced to match against nothing, guaranteed failure.
The rule that SAN presence forces CN to be ignored is not a browser policy choice: it is mandated by RFC 5280’s definition of the SAN extension as a critical extension. When an X.509 extension is marked critical, clients that do not understand it must reject the certificate. For SAN, even when not marked critical in the formal sense, the RFC explicitly states that CN must be ignored when SAN is present. This is why adding a SAN to an existing CN-only certificate can introduce failures: if the SAN is added but does not include the correct hostname, the CN (which previously matched) is now ignored and the certificate fails.
The CN-to-SAN Browser Transition: Timeline and Current Status
The transition from CN-based to SAN-only hostname validation happened over several years with browser-specific enforcement dates:
| Browser / Client | When CN was dropped | Current behavior | Error shown |
| Chrome | Chrome 58, March 2017 | SAN-only matching. CN is completely ignored for hostname validation. | ERR_CERT_COMMON_NAME_INVALID |
| Firefox | Firefox 48, August 2016 (partially); full enforcement followed Chrome | SAN-only matching. CN is ignored. | SEC_ERROR_UNKNOWN_ISSUER or certificate hostname mismatch warning |
| Safari | Enforced with macOS Sierra and iOS 10 (2016) | SAN-only matching. | Certificate error page |
| Edge (Chromium-based) | Follows Chrome behavior (Chromium 58+) | SAN-only matching. CN is ignored. | ERR_CERT_COMMON_NAME_INVALID |
| OpenSSL (command-line, libssl) | OpenSSL 1.1.0 (2016) by default | SAN-only matching by default; CN fallback available via configuration flag but not recommended | Certificate verification failed |
| curl | curl 7.66.0+ (2019) by default | SAN-only matching. | SSL: certificate subject name mismatch |
| Python requests | Recent versions | SAN-only via certifi/ssl module | ssl.SSLCertVerificationError |
The CA/B Forum Baseline Requirements codified this in Section 7.1.4.2.1 (2016): CAs must include a SAN extension in all publicly-trusted TLS certificates and the SAN must contain the certificate’s domain name(s). The Common Name may still be included in the Subject field but its value is now irrelevant to hostname validation.
RFC 9525 (September 2023, ‘Service Identity in TLS’) superseded RFC 6125 and serves as the current authoritative reference for service identity validation in TLS. It explicitly codifies that clients must use the SAN extension for identity matching and provides the current rules for how each SAN type is matched.
Subject Alternative Name Types: What Each Does and How It Is Matched
The SAN extension supports multiple general name types. Each type has different matching rules and different use cases.
dNSName: domain names
The most common SAN type. Specifies a fully-qualified domain name or a wildcard pattern. Used for HTTPS server certificates and any certificate where the connecting party uses a DNS hostname.
Matching rules for dNSName:
- Exact match: the hostname in the connection must exactly match the dNSName entry (case-insensitive).
- Wildcard match: a dNSName value of *.example.com matches any single-label subdomain (www.example.com, shop.example.com) but not the bare domain (example.com) and not multi-level subdomains (login.shop.example.com).
- The wildcard asterisk must be the leftmost label only. Patterns like shop.*.example.com are not valid wildcards.
- Partial-label wildcards (s*.example.com) are defined in RFC 5280 but restricted or forbidden by CA/B Forum Baseline Requirements for publicly trusted certificates.
- Trailing dots are handled: example.com and example.com. are typically treated as equivalent.
iPAddress: IP addresses
Specifies an IP address the certificate is valid for. Used when clients connect to a server using an IP address rather than a hostname (internal infrastructure, network devices, services not accessed via DNS).
Matching rules for iPAddress:
- Exact binary match: the IP address in the connection must exactly match the binary-encoded IP address in the SAN.
- No wildcards, no CIDR notation, no subnet ranges. A single iPAddress SAN entry covers exactly one IP address.
- IPv4 addresses are stored as 4-byte binary values. IPv6 addresses are stored as 16-byte binary values.
- An IP address as a string in the dNSName field (e.g., DNS:192.168.1.1 instead of IP:192.168.1.1) is a certificate error and will not match IP connections.
This is one of the most common certificate generation mistakes for internal infrastructure certificates. If a service is accessed by IP address, the IP must appear in the SAN as an iPAddress entry (IP:192.168.1.1), not as a dNSName entry (DNS:192.168.1.1). Tools that generate certificates with IP addresses in the dNSName field produce certificates that fail IP-based connections even though the IP address is technically present in the certificate.
rfc822Name: email addresses
Specifies an email address. Used in S/MIME certificates to bind the certificate to a specific email mailbox. Not used in TLS server certificates. The rfc822Name type is what email clients check when validating an S/MIME signature: the email address in the From field must match an rfc822Name entry in the signer’s certificate.
Matching rules: case-insensitive match against the email address. The domain portion is matched case-insensitively; the local part (before the @) matching rules vary by application.
uniformResourceIdentifier: URIs
Specifies a URI. In classical TLS server certificates, this was rarely used. In modern service mesh and workload identity contexts, URI SANs are the primary identity mechanism for SPIFFE (Secure Production Identity Framework for Everyone) IDs.
A SPIFFE ID is a URI in the format spiffe://trust-domain/path, for example spiffe://example.org/service/billing. Service meshes (Istio, Linkerd, Consul Connect) issue certificates with SPIFFE ID URI SANs to identify services. When service A connects to service B using mTLS, service B verifies that service A’s certificate contains the expected SPIFFE ID URI SAN. This provides workload identity without relying on DNS hostnames, which change as pods are scheduled and rescheduled in Kubernetes.
OtherName: UPN and custom types
The OtherName general name type is an extensibility mechanism that allows arbitrary typed identities to be embedded using an OID. The most common use is the User Principal Name (UPN), used in Windows Active Directory environments for smartcard and client certificate authentication. A UPN SAN identifies a user account in the format user@domain.com stored with OID 1.3.6.1.4.1.311.20.2.3.
When a user authenticates via smartcard or certificate-based login on Windows, Active Directory validates the UPN from the OtherName SAN against the user’s account in the directory. This is separate from TLS server certificate hostname validation; it is identity verification for client certificates in enterprise authentication scenarios.
SAN Types: Complete Reference
| SAN type | RFC 5280 name | Typical use | Matching rule | Common mistake |
| dNSName | dNSName | HTTPS server certificates; any DNS-based service | Exact or wildcard single-label match; case-insensitive | Putting IP addresses in dNSName instead of iPAddress |
| iPAddress | iPAddress | Server certificates for IP-based access; internal infrastructure | Exact binary match; no wildcards or subnets | Encoding IP as string in dNSName or encoding as text string instead of binary |
| rfc822Name | rfc822Name | S/MIME email certificates | Case-insensitive email address match | Including email address in dNSName instead of rfc822Name |
| uniformResourceIdentifier | uniformResourceIdentifier (URI) | SPIFFE workload identity; specialized service identity | Exact URI match; case rules depend on URI scheme | Using URI for hostname identity instead of dNSName |
| OtherName (UPN) | otherName with OID 1.3.6.1.4.1.311.20.2.3 | Windows client authentication, smartcard login | Exact UPN match against AD user account | Using rfc822Name instead of OtherName with correct OID |
| directoryName | directoryName | Rare; distinguished name as identity | Exact DN match | Rarely encountered in practice |
The Browser Validation Algorithm: Step by Step
When a browser connects to an HTTPS server, the certificate validation sequence for hostname checking is:
- The browser extracts all SAN entries of type dNSName and iPAddress from the certificate’s SAN extension.
- If the connection was made using a DNS hostname (e.g., www.example.com), the browser checks each dNSName entry for an exact or wildcard match against the connecting hostname.
- If the connection was made using an IP address, the browser checks each iPAddress entry for an exact binary match.
- If any SAN entry matches, the check passes.
- If no SAN entry matches AND the certificate has a SAN extension, the check fails regardless of what the CN says.
- If the certificate has no SAN extension (very old certificates), some clients attempt CN fallback. Current browsers do not; they fail.
The CN is never checked for hostname matching by any current major browser. Its value is displayed in certificate details panels for human reading, but it plays no role in the cryptographic validation.
Common SAN Mistakes and the Errors They Produce
ERR_CERT_COMMON_NAME_INVALID (Chrome)
This error means the hostname the browser used to connect is not in any dNSName SAN entry. Despite the name referencing ‘Common Name’, this error fires when the SAN validation fails, not when the CN fails. The CN is not checked. Causes: certificate issued for a different domain, missing www or non-www variant, IP address in connection but no iPAddress SAN, certificate for *.example.com but connecting to sub.sub.example.com.
Missing www / non-www variant
A certificate for example.com does not cover www.example.com, and a certificate for www.example.com does not cover example.com. Both should be included as separate dNSName SAN entries. Let’s Encrypt automatically includes both when issuing for either. Paid CA orders may require explicit inclusion of both variants in the CSR.
The OpenSSL CSR SAN problem
When generating a CSR with OpenSSL, SAN extensions specified in the CSR are not automatically copied to the signed certificate unless the signing configuration explicitly copies them. This is a common source of certificates that appear to have SANs in the CSR but arrive without them.
| # Generating a CSR with SANs using OpenSSL (modern approach):
$ openssl req -new -key private.key -out request.csr \ -subj ‘/CN=example.com’ \ -addext ‘subjectAltName=DNS:example.com,DNS:www.example.com,IP:192.168.1.100’
# The -addext flag (OpenSSL 1.1.1+) embeds SANs in the CSR. # When a CA processes this CSR, they add SANs from their own validation, # not necessarily from the CSR. For self-signed or internal CA certificates:
# Self-signed certificate with SANs (one command): $ openssl req -x509 -newkey rsa:2048 -nodes \ -keyout private.key \ -out certificate.pem \ -days 365 \ -subj ‘/CN=example.com’ \ -addext ‘subjectAltName=DNS:example.com,DNS:www.example.com,IP:192.168.1.100’
# Verify SANs are present in the resulting certificate: $ openssl x509 -in certificate.pem -noout -text | grep -A5 ‘Subject Alternative Name’ # Should show: DNS:example.com, DNS:www.example.com, IP Address:192.168.1.100
# If using an internal CA to sign a CSR, the CA config must copy extensions: # In the signing config (openssl.cnf), ensure: copy_extensions = copy # Without this, SANs in the CSR are dropped from the signed certificate. |
The -addext flag requires OpenSSL 1.1.1 or later. Older OpenSSL versions require creating a separate config file to specify SANs for certificate generation. Using the older approach with a config file is still required when signing CSRs from external sources; the -addext flag only works for self-signed certificates and CSR generation with the same openssl req command.
IP address in dNSName instead of iPAddress
A certificate where an IP address appears as DNS:192.168.1.1 in the SAN extension instead of IP Address:192.168.1.1 will fail validation when a client connects via that IP address. The browser performs IP validation against iPAddress SAN entries only; dNSName entries are only for DNS hostname matching. Verify using openssl x509 -in cert.pem -noout -text and check whether the IP appears under IP Address: or DNS: in the Subject Alternative Name output.
Frequently Asked Questions
Why does Chrome show ERR_CERT_COMMON_NAME_INVALID when my CN matches?
Chrome dropped CN-based hostname matching in Chrome 58 (March 2017). The error name is historical; it fires when SAN validation fails, not when CN fails. Chrome does not check the CN for hostname validation at all. The certificate must have a dNSName SAN entry that matches the connecting hostname. If the certificate was issued before Chrome 58 enforcement and only has a CN without SAN entries, it will fail in Chrome regardless of the CN value. The fix is to reissue the certificate with the correct hostname(s) in the SAN extension.
When was the Common Name deprecated for hostname matching?
RFC 2818 (May 2000) recommended using SAN over CN for hostname validation and stated that if SAN is present, CN must not be checked. The CA/B Forum Baseline Requirements (2016) mandated that CAs include SAN in all publicly trusted TLS certificates. Chrome 58 (March 2017) removed CN fallback. Firefox and Safari implemented equivalent enforcement around the same period. RFC 9525 (September 2023) superseded RFC 6125 and is the current authoritative standard for service identity in TLS, codifying SAN-only hostname validation as the required behavior.
Does a wildcard in the SAN cover all subdomains?
A wildcard dNSName SAN (*.example.com) covers all single-label first-level subdomains: www.example.com, shop.example.com, and any other name with exactly one label before .example.com. It does not cover the bare domain (example.com itself), and it does not cover second-level subdomains (login.shop.example.com). Each level of depth requires a separate wildcard entry or an explicit dNSName entry.
Can an SSL certificate contain both dNSName and iPAddress SANs?
Yes. A single certificate can contain multiple SAN entries of different types. A certificate might list both DNS:example.com and IP Address:192.168.1.1, allowing it to be used for connections made either via the hostname or via the IP address. Each type is checked against its corresponding connection method: dNSName against DNS hostname connections, iPAddress against IP address connections. Mixing SAN types in a single certificate is valid and common for internal infrastructure certificates.
What is a SPIFFE URI SAN and when is it used?
A SPIFFE (Secure Production Identity Framework for Everyone) ID is a URI in the format spiffe://trust-domain/workload-identifier, stored as a uniformResourceIdentifier SAN in the certificate. SPIFFE IDs are used in service mesh environments (Istio, Linkerd, Consul) to provide workload identity for microservices. When service A calls service B over mTLS, service B’s admission policy can verify that service A’s certificate contains the expected SPIFFE ID, providing service-to-service authentication based on workload identity rather than DNS names. SPIFFE URI SANs are issued by the service mesh’s internal certificate authority and are not present in standard web server certificates.
