Connection Errors vs Certificate Errors
SSL errors split into two distinct failure modes, and mixing them up wastes debugging time.
Certificate errors happen after the TLS handshake completes — the connection negotiates fine, but the browser rejects the certificate itself. Causes: expired validity dates, a hostname that doesn't match the Subject Alternative Name (SAN) list, or an issuer the browser's trust store doesn't recognize. Per RFC 5280 §6, this is the certification path validation algorithm — every browser walks the chain from leaf to root and each step can fail independently.
Connection errors happen before a certificate is even evaluated. The client and server can't agree on a TLS protocol version or cipher suite, SNI (Server Name Indication) is stripped by a middlebox, or something is serving plain HTTP on port 443. NET::ERR_SSL_PROTOCOL_ERROR is the signature symptom — see the SSL protocol error guide for a full breakdown.
Knowing which bucket you're in narrows the fix immediately: certificate errors are fixed by reissuing or reinstalling a cert; connection errors are fixed by adjusting server TLS configuration or removing whatever is intercepting the handshake.
Cross-Browser SSL Error Decoder
Every browser reports the same underlying failures with different strings. This table maps them to one root cause so you don't have to guess twice.
| Root Cause | Chrome | Firefox | Safari |
|---|---|---|---|
| Certificate expired | NET::ERR_CERT_DATE_INVALID | SEC_ERROR_EXPIRED_CERTIFICATE | "This Connection Is Not Private" |
| Hostname/SAN mismatch | NET::ERR_CERT_COMMON_NAME_INVALID | SSL_ERROR_BAD_CERT_DOMAIN | "This Connection Is Not Private" |
| Untrusted or self-signed issuer | NET::ERR_CERT_AUTHORITY_INVALID | SEC_ERROR_UNKNOWN_ISSUER | "This Connection Is Not Private" |
| Weak signature algorithm (SHA-1) | NET::ERR_CERT_WEAK_SIGNATURE_ALGORITHM | SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED | "This Connection Is Not Private" |
| TLS handshake / protocol mismatch | NET::ERR_SSL_PROTOCOL_ERROR | SSL_ERROR_NO_CYPHER_OVERLAP | "Safari Can't Establish a Secure Connection" |
| MITM / antivirus HTTPS interception | NET::ERR_CERT_AUTHORITY_INVALID | MOZILLA_PKIX_ERROR_MITM_DETECTED | "This Connection Is Not Private" |
Safari collapses most certificate failures into one generic message — engineers on macOS should confirm the specific cause with openssl s_client rather than trusting the wording alone.
The 6 Most Common SSL Errors
1. Expired certificate. The certificate's notAfter date has passed. Fix: renew immediately and automate future renewal with Certbot or another ACME client so this can't recur — see the SSL expiry monitoring guide for a renewal-automation setup.
2. Hostname / Common Name mismatch. The URL's hostname isn't listed in the certificate's SAN field — commonly because a cert was issued for example.com but the site also serves www.example.com, or a wildcard cert doesn't cover a second-level subdomain. Fix: reissue the certificate with every hostname the site actually serves listed in SAN.
3. Untrusted or self-signed issuer. The issuing CA isn't in the client's trust store, or the certificate is self-signed. Legitimate for internal/dev environments; a real problem in production. Fix: install a certificate from a publicly trusted CA (Let's Encrypt is free and automatable — see its certificate hierarchy documentation).
4. Incomplete certificate chain. The server sends the leaf certificate but not the intermediate CA certificate. Some browsers cache intermediates from prior visits or fetch them via Authority Information Access (AIA), which is why this error is inconsistent — "works in Chrome, fails in Firefox" is the classic symptom. Fix: configure the server to serve the full chain (leaf + intermediate), not just the leaf. Full breakdown in the certificate chain validation guide.
5. Weak signature algorithm (SHA-1). Chrome has blocked SHA-1-signed certificates since Chrome 56, following Google's 2017 SHA-1 collision research. Fix: reissue with SHA-256.
6. TLS handshake / protocol error. Server doesn't support a TLS version the client offers, a firewall strips SNI, or something non-HTTPS is listening on port 443. Fix: confirm the server supports TLS 1.2 and 1.3, check the listener configuration, and rule out network-level interception. Full playbook: SSL handshake failed guide.
Diagnosing with OpenSSL
Browser error text tells you the symptom; openssl s_client tells you the exact cause. Run this against any host:
openssl s_client -connect example.com:443 -servername example.com
Add -showcerts to print every certificate in the chain the server sent — useful for spotting a missing intermediate:
openssl s_client -connect example.com:443 -servername example.com -showcerts
A healthy chain ends with Verify return code: 0 (ok). Real failure output identifies the problem directly via the X509_V_ERR_* codes documented in OpenSSL's verify manual:
depth=0 CN = example.com
verify error:num=10:certificate has expired
Verify return code: 10 (certificate has expired)
depth=0 CN = example.com
verify error:num=18:self signed certificate
Verify return code: 18 (self signed certificate)
depth=1 CN = Some Intermediate CA
verify error:num=20:unable to get local issuer certificate
Verify return code: 21 (unable to verify the first certificate)
Once you've confirmed the root cause with openssl s_client, run the domain through the SSL Checker to get a formatted report — chain status, expiry countdown, and protocol support in one view — before and after applying a fix.
Why Expiry Errors Are Becoming More Common
Certificate lifetimes are shrinking industry-wide. Per the CA/Browser Forum's Ballot SC081v3, maximum certificate validity dropped to 200 days as of March 15, 2026, and is scheduled to fall to 100 days in 2027 and 47 days by March 2029. Shorter lifetimes reduce the window an attacker can exploit a compromised key, but they also mean a manual renewal process that "mostly worked" at 398 days will fail far more often at 47. If your team still renews certificates by hand, NET::ERR_CERT_DATE_INVALID is going to become a recurring incident rather than a rare one — automate renewal now with an ACME client, and pair it with uptime alerts so an expiry never reaches production silently.
Stop checking manually. DNSnexus Monitor watches your SSL expiry, DNS records, email auth, and blacklist status — and alerts you before things break. Free tier covers one domain.
Common Issues & Troubleshooting
"It works on my phone but not my laptop" (or vice versa). Almost always a missing intermediate certificate — some devices cache or fetch intermediates via AIA, others don't. Serve the full chain from the server rather than relying on client-side fetching.
Error persists after renewing the certificate. The web server (nginx, Apache, load balancer) is likely still serving the cached old certificate from memory. Restart or reload the TLS-terminating service after every renewal — a reload without a full restart is often enough (nginx -s reload, apachectl graceful).
Error only happens on corporate or public Wi-Fi. Check for antivirus HTTPS scanning (Avast, Kaspersky) or a corporate MITM proxy injecting its own root certificate. Firefox's MOZILLA_PKIX_ERROR_MITM_DETECTED explicitly flags this. Disable HTTPS scanning in the AV settings or have IT install the proxy's root cert into the trust store.
System clock is wrong. A client with the wrong date/time will reject valid certificates as expired or not-yet-valid. This is the single most common client-side cause of NET::ERR_CERT_DATE_INVALID reports that turn out not to be server bugs at all — check the client's date before touching the server.
Frequently Asked Questions
Q: What does an SSL error actually mean?
It means the browser either couldn't complete the TLS handshake with the server, or completed it but rejected the certificate presented — because it's expired, doesn't match the hostname, or was issued by an untrusted authority.
Q: How do I fix NET::ERR_CERT_AUTHORITY_INVALID?
Confirm the certificate comes from a publicly trusted CA (not self-signed) and that the server sends the full intermediate chain. Run openssl s_client -connect yourdomain:443 -servername yourdomain to see the exact verify error before making changes.
Q: Is it safe to click "Proceed anyway" past an SSL warning?
No, not on a production site handling real user data — the warning means the connection can't be verified as private, so credentials or data submitted could be exposed to an interceptor. It's acceptable only on known internal/dev environments you control.
Q: How do I know if my SSL certificate is expired?
Run it through the SSL Checker for an instant expiry date, or use openssl s_client -connect yourdomain:443 | openssl x509 -noout -dates to print notBefore and notAfter directly.
Q: Why do I get an SSL error on one network but not another?
This usually points to a MITM proxy or antivirus HTTPS scanner on the failing network injecting its own certificate that the browser doesn't fully trust — not a problem with the site's certificate itself.
Q: What causes a missing intermediate certificate error?
The server is configured to send only the leaf certificate, not the CA's intermediate certificate. Some browsers tolerate this by fetching the intermediate separately; others fail outright — fix it server-side by serving the complete chain.
Q: How long do SSL certificates last in 2026?
A maximum of 200 days as of March 15, 2026, per CA/Browser Forum Ballot SC081v3 — down from 398 days previously, and scheduled to shrink further to 47 days by 2029.
Next Steps
Run any domain through the SSL Checker to get chain status, expiry countdown, and protocol details in one report, and use the DNS Propagation Checker if a recent certificate or server change hasn't taken effect everywhere yet. For deeper dives into specific failure modes, see the SSL handshake failed guide, the SSL protocol error guide, and the certificate chain validation guide.