How to check certificate SAN
Print the extension: openssl x509 -noout -ext subjectAltName, fed from openssl s_client -connect host:443 -servername host </dev/null. The DNS: entries are the only names a modern client accepts. To test one hostname against them without reading the list, run openssl x509 -noout -checkhost www.example.com.
Why check this
Subject Alternative Name decides which hostnames the certificate covers, and a deployment that adds an alias without reissuing breaks every client on that alias while the main site stays green. Run this whenever a new hostname, a new region or a new environment alias appears in DNS, and before a release that moves traffic from app.example.com to www.app.example.com. The failure is total for the affected name: no retry, no partial content.
Renewal is the moment the list drifts. A certificate is reissued from whatever request the pipeline builds today, so a name that was added by hand to the previous one disappears without a warning anywhere: the new certificate is valid, the chain is intact, the expiry is fresh, and one hostname stops working. Nothing in a monitor that checks expiry alone will see it. That is why this check reads the list rather than the dates, and why the list belongs in the release ticket next to the hostnames the service is supposed to answer on.
Prerequisites
- openssl 1.1.1 or later. See the x509 manual for
-extand-checkhost. - The list of hostnames clients actually use, taken from DNS and from the client configuration, not from memory.
- A writable directory. Step 2 saves the certificate so the later checks make no further connections.
Steps
- Step 1.
Print the names on a healthy certificate.
openssl s_client -connect www.cloudflare.com:443 -servername www.cloudflare.com </dev/null 2>/dev/null | openssl x509 -noout -ext subjectAltNameX509v3 Subject Alternative Name: DNS:blog.api.www.cloudflare.com, DNS:www.cloudflare.comTwo names, both exact. This certificate covers nothing else, wildcard or otherwise.
- Step 2.
Save the certificate of the host under test once.
openssl s_client -connect wrong.host.badssl.com:443 -servername wrong.host.badssl.com </dev/null 2>/dev/null | openssl x509 -outform PEM | tee badssl.pem | head -1-----BEGIN CERTIFICATE----- - Step 3.
Read the subject and the names side by side.
openssl x509 -in badssl.pem -noout -subject -ext subjectAltNamesubject=CN = *.badssl.com X509v3 Subject Alternative Name: DNS:*.badssl.com, DNS:badssl.comThe wildcard is repeated in the subject, but only the
DNS:line is consulted. - Step 4.
Test each hostname you serve against the saved file.
for name in badssl.com www.badssl.com wrong.host.badssl.com a.b.badssl.com; do printf '%-24s ' "$name"; openssl x509 -in badssl.pem -noout -checkhost "$name"; donebadssl.com Hostname badssl.com does match certificate www.badssl.com Hostname www.badssl.com does match certificate wrong.host.badssl.com Hostname wrong.host.badssl.com does NOT match certificate a.b.badssl.com Hostname a.b.badssl.com does NOT match certificate*.badssl.comcovers one label and no more. Two labels below the domain fail. - Step 5.
Watch the same mismatch during a live handshake.
openssl s_client -brief -connect wrong.host.badssl.com:443 -servername wrong.host.badssl.com -verify_hostname wrong.host.badssl.com </dev/nulldepth=0 CN = *.badssl.com verify error:num=62:hostname mismatch CONNECTION ESTABLISHED Peer certificate: CN = *.badssl.com Verification error: hostname mismatch DONEWithout
-verify_hostname,s_clientreports the chain as valid and says nothing about the name. - Step 6.
Confirm that the name does not depend on the Common Name at all.
openssl s_client -connect no-common-name.badssl.com:443 -servername no-common-name.badssl.com </dev/null 2>/dev/null | openssl x509 -noout -subject -ext subjectAltNamesubject=C = US, ST = California, L = Walnut Creek, O = Lucas Garron, OU = Multi-Domain SSL X509v3 Subject Alternative Name: DNS:no-common-name.badssl.comNo
CNin the subject, and-checkhost no-common-name.badssl.comagainst this certificate still answers "does match". The name lives in the extension. This certificate also expired in 2020, so a browser rejects the host for a different reason.
How to read the result
| What you see | What it means | What to do |
| --- | --- | --- |
| Every hostname you serve appears as DNS: | The certificate covers the traffic | Pass. Keep the list in the release ticket. |
| does NOT match certificate | That hostname fails for every client | Reissue with the name added. No server setting fixes it. |
| verify error:num=62:hostname mismatch | The live handshake rejects the name | Same defect, observed end to end. |
| A DNS: entry with two wildcards, such as *.*.example.com | openssl refuses to match a.b.example.com against it | Replace with explicit names or a single wildcard per level. |
| IP Address: entries only | Name-based clients have nothing to match | Add the DNS names. An IP entry is used only when the client dials the IP. |
Common mistakes
What to check next
- How to check SSL certificate from command line: the rest of the fields on the certificate you saved.
- How to check certificate chain: the names can be right while the path to a root is broken.
- How to check SSL certificate in chrome: the same list through the browser certificate viewer.
- How to test SSL configuration: the full pass this check belongs to.
- Ssl certificate checker: reads the names from a server without a terminal.
FAQ
How to check subject alternative names in a certificate?
Step 1 for a live server, openssl x509 -in cert.pem -noout -ext subjectAltName for a file. Both print the extension verbatim, including IP Address: and email: entries when a certificate carries them.
Does a wildcard cover a sub-subdomain?
No. One label only, confirmed by step 4. *.example.com matches api.example.com and rejects v1.api.example.com. Nested coverage needs a second wildcard entry such as *.api.example.com.
Is the Common Name used by any client?
curl reports a failure as "no alternative certificate subject name matches target hostname", which names the extension and not the subject. Treat the SAN list as the answer, and treat a matching Common Name as decoration that costs nothing to keep.
How do I check the names before the certificate is issued?
Read them off the signing request: openssl req -in req.csr -noout -text | grep -A1 'Subject Alternative Name'. A request built without -addext subjectAltName carries no names, and the authority will add whatever its own form says.
Does the order of the DNS: entries matter?
No. A client scans the whole list and accepts a match anywhere in it, so the first entry has no special standing. The order you see is the order the authority wrote, and it can change between two renewals of the same certificate. Compare the entries as a set, not as a sequence, or a diff between two renewals reports a change that is not one.
Verified
Verified by Maks Vernyopenssl 3.1.1
Each output block is what the command above it printed on that date, on the host named in the step. Figures read from a live site move between runs. Compare the shape of the answer rather than the digits, and see the methodology for how a page is re-verified.
Related on this site
basic6 minpublished updated Maks Verny