A site whose certificate expired ten minutes ago is, by every protocol-level definition, broken. Browsers refuse to load it. Mobile apps drop connections. Internal services that depended on it can't talk to each other. The fix takes about five minutes if the right person notices fast and zero minutes if a renewal calendar was wired up correctly. The fact that calendar-bound certificate failures still take down major sites — including ones owned by companies that should know better — is one of the most predictable categories of preventable outage in the industry.
What "expired" actually means ¶
Every TLS certificate carries a notBefore date and a notAfter date. After notAfter, the certificate is no longer considered valid, full stop. Browsers refuse to negotiate a TLS session and show a warning page (Chrome's NET::ERR_CERT_DATE_INVALID; Firefox's SEC_ERROR_EXPIRED_CERTIFICATE). API clients without an interactive UI just disconnect, often with a generic "TLS handshake failed" message that doesn't make the cause obvious. The website is reachable; the network path is fine; the certificate is the only thing wrong, and that's enough to break everything that depends on it.
Certificate validity periods have shrunk over time. They used to be 5+ years. CA/Browser Forum rules now cap them at 398 days for publicly-trusted certs (down from 825 in 2020 and 5+ years before 2018). Apple, Google, Mozilla, and Microsoft enforce shorter limits in their root programs — public certs over 398 days are simply rejected by modern browsers. The push toward 90 days (the Let's Encrypt default) is industry-wide; Google has openly proposed 47 days as the next ceiling. Shorter validity makes mis-issuance recoverable faster but also makes manual renewal even more failure-prone.
The calendar-bound outage shape ¶
Certificate failures have a fingerprint unlike any other outage: they happen at exactly midnight UTC on a specific day, and they happen even though absolutely nothing in the system changed. The signature is unmistakable on a status timeline — every dashboard reading is green at 23:59 UTC, and every reading is red at 00:01 UTC. No deploy, no traffic spike, no infrastructure event. Just the calendar.
Famous instances of this shape:
- Microsoft Teams, January 2020 (and again April 2021): the certificate behind Teams' authentication path expired without renewal. Logins broke globally for several hours. Twice. The post-incident response was a calendar of expirations posted publicly.
- LinkedIn intermittent outages, late 2017: certificate-pinning issues compounded by an expired intermediate.
- Spotify, intermittent through the 2010s: client certificate-pinning broke when a backend cert rotated unexpectedly; mobile apps would refuse to connect.
- Pokémon Go, 2018: mobile-app TLS pinning against a specific CA broke the game when the CA was distrusted.
- The 2024 Entrust distrust: Chrome announced it would stop trusting Entrust certificates issued after October 2024. Hundreds of sites that had bought multi-year Entrust certs scrambled to migrate; some didn't, and broke for Chrome users on the cutoff date even though the certificates themselves had not yet "expired" by the date stamp.
Why this fails so often ¶
Renewal isn't technically hard. The reasons it fails are organizational, not protocol-level:
- The renewal process was manual and the engineer who set it up left the company. The renewal calendar was in their head. Nobody else knew.
- Auto-renewal was set up but a config drift broke it. The cert's renewal cron job is on a host that's been retired. The renewal succeeded but the new cert wasn't deployed because the service that consumes it was rotated to a new container image that doesn't read from the same path. Auto-renewal that hasn't been tested by actually expiring a cert under controlled conditions is approximately untested.
- The notification went to a deprecated email. Many CAs send 90/30/7-day expiration warnings to the email on the registration. That email is often a long-departed engineer or a generic
admin@alias that gets ignored. - Internal-only certificates were forgotten. Site-facing certs get attention because users see them break. Internal-service-to-internal-service certs (mTLS in service meshes, internal CA chains for monitoring tools) often have looser monitoring; their expiry shows up as 502s or 504s in mysterious places that take longer to diagnose.
What to do as a user ¶
You can't fix a server's cert. Three honest options:
- Wait it out. Most major sites notice within an hour and renew within two. If it's a small operator, longer.
- Use the site through a different channel. If the consumer-facing cert expired but their mobile app pins a different cert, the app may keep working. The reverse is also possible.
- Bypass the warning manually. Browsers let you click through expired-cert warnings ("Advanced → Proceed to site"). This works for read-only browsing but fundamentally re-opens you to MITM risk for the duration of the bypass — anyone on your network path can intercept traffic to that site without you noticing because the browser has stopped doing the check that would catch it. Don't enter passwords or credit cards through a manual bypass. The warning is there for a reason.
What not to do: change the system clock to "before the expiration date" so the browser stops complaining. People do this. It works. It also breaks every other certificate-validating tool on the machine for the duration, and creates audit-trail problems if anything else depends on monotonic time. Don't.
What to do as an operator ¶
If you've just noticed your cert expired:
- Renew. If you use Let's Encrypt with certbot,
certbot renew --force-renewaloften does it. If you have a paid CA, the renewal flow is in their dashboard. If both fail, you can issue a new Let's Encrypt cert in 60 seconds for the same hostname (assuming you control the DNS or HTTP validation). - Deploy the new cert to every place it's served — origin servers, load balancers, CDN edge configs. A cert renewed but not deployed is the same outage.
- Restart anything that holds the old cert in memory. Nginx and Apache pick up new certs on graceful reload (
nginx -s reload); some applications cache the parsed cert in process memory and need a full restart. - Verify externally. Don't trust your own cache — check from a fresh client. /ssl on isitdown.io probes the public cert chain from outside your network and surfaces the actual expiration date the public sees, which is often what you actually want to verify.
If you've noticed before it's expired:
- Renew now. There's no reason to wait until the deadline.
- Audit the renewal pipeline. When did it last successfully run? Where would you find out if it failed silently next time?
- Inventory every cert your stack depends on. Public-facing, internal mTLS, client certs for third-party services, code-signing certs. Each one has a calendar deadline. Track them in one place.
Adjacent failure modes that look like expiration ¶
Not every cert error is "expired." Easy to confuse:
- Hostname mismatch: the cert is valid but doesn't cover the hostname you're loading. Common when a multi-domain cert was renewed without re-listing all the hostnames.
- Untrusted root: the cert chains up to a CA the browser doesn't trust. Most often a self-signed cert, or a CA that was distrusted (Symantec 2018, Entrust 2024).
- Incomplete chain: the server is sending the leaf certificate but not the intermediate(s) that link it to the root. Some clients (modern browsers) cache intermediates and recover; others (older Java versions, mobile platforms with limited trust stores) fail. /ssl shows whether the chain delivered to clients is complete.
- OCSP / CRL outage: the server providing revocation info is unreachable. Modern browsers usually soft-fail (treat as valid) but stricter clients fail closed.
FAQ ¶
How long until browsers notice the new cert after I renew?
Effectively immediately. There's no caching of "this site's cert is bad" beyond the current TLS session. The next handshake from a fresh client uses the new cert. Long-running connections (websockets, streaming) might hold onto the old session until they reconnect, but visiting the site cold gets you the new cert right away.
What's the right validity period to choose?
For public-facing certs you don't get to choose much — 398 days max, and 90 days for free CAs. For internal certs (your own internal CA), shorter is better than longer. 30-90 days forces you to keep the renewal pipeline working, which is the only way to prevent a 5-year outage hidden behind "we'll get to that next year."
Should I trust auto-renewal, given how often it fails silently?
Yes — but verify it. Set up an external monitor that alerts on cert expiry approaching. The point isn't to do the renewal manually; it's to catch the case where auto-renewal has silently broken. /ssl + a saved monitor with alerting solves this in a few minutes.
What about mTLS / internal certs that aren't browser-facing?
Same expiration mechanic, way less monitoring. The Microsoft Teams 2020 incident, the Cisco WebEx 2020 incident, and similar major-vendor outages have repeatedly turned out to be internal certs that nobody on the support side even knew existed. The lesson industry-wide has been: every cert anywhere goes into the inventory + the calendar.