The six X.509 fields that decide whether TLS works
Print a certificate in full and you get around sixty lines of structure: a version number, a serial, two distinguished names, a public key in hexadecimal, a dozen extensions and a signature block.
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null \
| openssl x509 -noout -text
Six things in that output explain nearly every certificate failure you will meet. The other fifty lines are correct, uninteresting, and occasionally reassuring.
The six
| Field | What it decides | The failure when it is wrong |
|---|---|---|
| Validity: Not Before, Not After | The window in which the certificate is accepted | Expired, or, less obviously, not yet valid |
| Subject Alternative Name | Which hostnames it covers | Name mismatch on one hostname out of six |
| Basic Constraints | Whether it may sign other certificates | A chain that cannot be built, or a leaf used as an intermediate |
| Extended Key Usage | What the certificate is allowed to be used for | A valid certificate rejected for TLS because it was issued for something else |
| Authority Information Access | Where to fetch the issuer, and where to ask about revocation | Works in one browser and fails in another client |
| Signature Algorithm | How the issuer signed it | Rejected outright by anything current if it is a retired algorithm |
The second row is a subject on its own, because a missing name is the most common certificate fault on a site with more than one hostname: the list browsers actually read.
Not Before, which nobody checks
Everyone reads the expiry. The other end of the window fails too, and it produces a bewildering incident because the certificate was issued minutes ago and is obviously fine.
Two causes. The server's clock is wrong, so a certificate valid from this morning appears to be from the future. Or a certificate was issued in a timezone-adjacent way and deployed immediately, and a client whose clock runs a few minutes behind rejects it for a short window.
The symptom is a security warning saying the certificate is not yet valid, on a certificate that is manifestly valid, on some machines and not others. Check the clock on the machine showing the error before you touch anything else.
openssl x509 -noout -dates -in cert.pem
date -u
Basic Constraints, the field that makes an authority
One boolean decides whether a certificate is allowed to sign other certificates.
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
CA:TRUE is an intermediate or a root. CA:FALSE, or the extension being absent, is a leaf, and a leaf cannot vouch for anything. pathlen caps how many further authorities may appear below it, which is why a pathlen:0 intermediate can sign server certificates and cannot sign another intermediate.
The practical case where this appears is somebody building a private authority who generates a certificate without the extension, uses it to sign a server certificate, and finds that nothing accepts the result. The signature is mathematically fine. The signer was not authorised to be a signer, and validation stops there.
Extended Key Usage, which quietly disqualifies a valid certificate
A certificate declares what it is for. For a website, the value that must be present is server authentication.
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
A certificate issued for code signing, or for email, or for client authentication only, is a perfectly valid, unexpired, correctly named certificate that a browser will refuse to accept for a web server. This turns up when somebody has a certificate lying around from another purpose and reuses it, and the error message rarely says which extension was the problem.
Critical, and why an unknown extension can be fatal
Notice the word critical in the Basic Constraints output above. It is not emphasis, it is a flag with defined behaviour.
RFC 5280 requires that a client encountering a critical extension it does not understand must reject the certificate. Non-critical extensions may be ignored when unrecognised. This is the mechanism that lets the format evolve without old software silently misinterpreting new fields, and it is the explanation for the otherwise inexplicable case where a certificate works everywhere except on one old device, which is refusing it because of an extension it has never heard of and has been told it may not ignore.
Authority Information Access, the field that fixes a broken chain
Two URLs live here. One points at the issuer's own certificate, the other at the responder that answers revocation questions.
openssl x509 -noout -text -in cert.pem | grep -A2 'Authority Information Access'
The first of those is more useful than it looks. The commonest chain fault is a server configured with only its own certificate and not the intermediate that signed it. Browsers frequently paper over this by fetching the missing certificate themselves, using precisely this URL, which is why the site looks fine in Chrome and fails in a script, a mobile app or an older client that does no such fetching.
It also means you can repair the situation without contacting anyone. Read the URL, download the intermediate, and append it to the served file:
curl -sO "$(openssl x509 -noout -text -in cert.pem \
| awk '/CA Issuers/{print $NF}' | sed 's/^URI://')"
Whether the chain being served is complete, as opposed to complete after your browser helped, is one of the questions the three openssl commands exist to answer.
What the certificate cannot tell you
Worth stating, because a great deal of time is lost inspecting a file when the problem is elsewhere.
It says nothing about the private key. A certificate and a key that do not belong together produce a server that will not start, or one that serves a handshake failure, and no amount of reading the certificate reveals it.
It says nothing about deployment. The file on your disk being correct and the file the server is presenting being correct are two claims, and on a host with several virtual hosts they diverge regularly.
And it says nothing about revocation. Whether a certificate has been withdrawn is a question asked of the issuer at connection time, not a property of the document, which is a separate mechanism with its own latency cost and its own failure modes.