// IT TOOLS & CALCULATORS
| 100+ TOOLS
๐Ÿ“š A FIELD GUIDE TO TLS/SSL CERTIFICATE ERRORS
Security guide ยท 1 Oct 2026 ยท 6 min read

Every TLS certificate error a browser can throw boils down to one of four actual causes: the certificate expired, nobody vouches for who issued it, it doesn't match the name you typed, or the chain connecting it to something trusted is broken. The browser's wording varies wildly across Chrome, Firefox and Safari, which is most of why these errors feel more mysterious than they are โ€” once you know which of the four buckets an error belongs to, the fix is almost always obvious.

Expired: the clock ran out, nothing else is wrong

Chrome shows NET::ERR_CERT_DATE_INVALID, Firefox shows "SEC_ERROR_EXPIRED_CERTIFICATE," Safari just says the certificate has expired โ€” all three mean the same thing: the certificate's notAfter field is in the past (or, less commonly, notBefore is in the future, usually from a server's clock being badly wrong). This is the simplest category because the fix is always the same โ€” issue a new certificate โ€” but it's also the one that recurs the most, because it's entirely preventable and entirely forgettable. Let's Encrypt certificates last 90 days specifically to force automation; a certificate that still needs a human to remember to renew it is a certificate that will eventually expire on a weekend. The actual fix for the underlying pattern, not just the one expired cert, is automated renewal (certbot, acme.sh, or your CDN/load balancer's built-in ACME support) plus a monitoring check that alerts well before expiry โ€” 30 days out, then again at 7 โ€” so a failed renewal job gets caught by a human before a customer does.

Self-signed and untrusted: nobody vouches for this certificate

NET::ERR_CERT_AUTHORITY_INVALID in Chrome, "the certificate is not trusted because the issuer certificate is unknown" in Firefox โ€” this means the certificate wasn't issued by (or doesn't chain up to) a Certificate Authority that the browser's trust store recognises. This is the expected, correct behaviour for a self-signed certificate, which is fine and normal for internal tools, local development, or infrastructure nobody outside your organisation needs to connect to โ€” the fix there isn't to "make the error go away," it's to either import that specific certificate into the trusted store of every machine that needs to connect to it, or run an internal CA (via something like step-ca or your organisation's existing PKI) and distribute its root certificate instead, which scales to many internal services without repeating the manual-trust step for each one.

It's a different, urgent problem when it shows up on something meant to be public: a misconfigured server accidentally serving its self-signed fallback certificate instead of the real one, a reverse proxy or load balancer terminating TLS with the wrong certificate attached, or โ€” the scenario this error exists to catch in the first place โ€” an active machine-in-the-middle attack on a network the user doesn't control. The error itself can't tell those apart; only context can. A public-facing service throwing this error needs the actual misconfiguration found and fixed, not the error suppressed.

Hostname mismatch: right certificate, wrong door

NET::ERR_CERT_COMMON_NAME_INVALID means the certificate is otherwise completely valid โ€” correctly issued, not expired, properly chained โ€” but doesn't cover the hostname you actually connected to. Modern browsers check the Subject Alternative Name (SAN) field exclusively; the older Common Name field is effectively decorative today, which trips people up when they issue a cert with the right CN but forget to add the matching SAN entries. The classic version of this is a certificate issued for example.com that doesn't also list www.example.com (or vice versa) โ€” browsers treat those as different hostnames requiring separate SAN coverage, not interchangeable variants of the same domain.

This also shows up constantly with load balancers and reverse proxies serving multiple backend services behind one IP: if the proxy presents a certificate covering only one of the hostnames it fronts, every other hostname routed through it fails with a mismatch, even though the backend itself is perfectly healthy. The fix is either a proper multi-SAN certificate listing every hostname the proxy serves, or a wildcard certificate (*.example.com) if the hostnames share a single subdomain level โ€” wildcards don't cover the bare apex domain or multiple levels of subdomain, which is its own common source of a mismatch people don't expect.

Broken chain: the missing middle link

A certificate chain runs from the leaf certificate (the one for your actual domain) through one or more intermediate certificates up to a root that's already in the browser's trust store. Chrome's "there is a problem with this site's certificate" with a chain-related detail, or curl's blunt unable to get local issuer certificate, almost always means the server sent the leaf certificate but not the intermediate(s) needed to connect it to a trusted root. This is the single most common real-world TLS misconfiguration, and it's confusing because it's inconsistent by design: browsers maintain their own cache of commonly-seen intermediate certificates (AIA chasing fetches a missing one automatically in many cases), so a misconfigured server can look perfectly fine in Chrome while failing in curl, a mobile app's bundled HTTP client, or any tool that doesn't do that automatic fetching. "It works in my browser" is specifically not evidence the chain is correctly configured.

The fix is serving the full chain โ€” leaf plus every required intermediate, in the correct order, root excluded (the root is supposed to already be on the client, and some strict validators actually reject a chain that includes it) โ€” in a single concatenated bundle. Every major CA publishes the correct intermediate bundle for exactly this purpose; the error is almost always a server configuration that only has the leaf certificate installed rather than the full chain file.

Diagnosing from the command line instead of the browser

A browser's padlock icon and error page are the least informative place to diagnose any of this, because browsers deliberately hide most of the chain detail behind extra clicks and auto-fetch missing intermediates in ways that mask real server misconfigurations. openssl s_client -connect example.com:443 -servername example.com shows the actual chain the server sent, in the order it sent it, with none of the browser's automatic patching โ€” if the intermediate is missing, this is where it's obviously missing, with a visibly shorter certificate chain than expected. Piping that through openssl x509 -noout -dates on the leaf certificate gives the exact expiry timestamps without hunting through a GUI, and -noout -ext subjectAltName lists every hostname actually covered, which immediately confirms or rules out a SAN mismatch rather than guessing from the error text. These three checks together cover all four categories from one command-line session, and they're exactly what a monitoring script should be running on a schedule rather than waiting for a user to report a broken padlock.

Errors that look like certificate problems but aren't

Two situations consistently get misdiagnosed as certificate errors when the certificate itself is completely fine. The first is HSTS (HTTP Strict Transport Security): once a browser has seen a valid HSTS header from a domain, it refuses to even attempt an HTTP connection or accept a certificate exception for that domain for the lifetime of the max-age value, which can be a year or more โ€” so a genuinely temporary certificate problem can appear to lock out "bypass this warning" entirely, because HSTS specifically removes that option for domains that opted into it. The second is mixed content: a page served correctly over HTTPS that loads a script, stylesheet or image over plain HTTP gets blocked or flagged by the browser in a way that's easy to mistake for a certificate trust issue, when the actual certificate on the page itself was never in question. Both are worth ruling out early, since neither one is fixed by touching the certificate at all.

Reading the certificate instead of guessing

All four categories live in fields that are trivial to inspect directly once you know to look: issuer and chain for trust problems, SAN entries for mismatches, notBefore/notAfter for expiry, and the intermediate count for chain issues. Checking these directly โ€” rather than inferring from the browser's often-vague wording โ€” turns "something's wrong with the certificate" into a specific, fixable fact in under a minute, and it's the same handful of fields every single time regardless of which of the four buckets the actual error falls into.