← Back to blog

Your SSL certificate expires in production, not in staging

2026-09-07

guidetls

On February 3, 2020, Microsoft Teams went down for hours because a TLS certificate expired. In December 2018, tens of millions of O2 and SoftBank subscribers lost mobile data for a day — an expired certificate inside Ericsson's packet-switch software. In August 2020, Spotify went quiet for an hour: a wildcard cert nobody renewed. These are companies with dedicated SRE organizations, and the failure mode is the same one that hits a two-person SaaS.

What makes certificate expiry special among outages is that it is the only one with a published date. The certificate tells anyone who asks exactly when it will stop working, months in advance. There is no traffic spike to predict, no disk to watch fill up. The information is sitting in the handshake. An expiry outage is not bad luck — it's an unread calendar.

So why does it keep happening?

Renewal automation fails silently

"We use Let's Encrypt, certbot renews automatically" is where most teams stop thinking about this — and automation genuinely solved the common case. But renewal automation fails in ways that produce no error you'll see:

  • The cron job that runs certbot dies with the server migration, and the cert stays valid for another 60 days. Plenty of time to forget.
  • The DNS-01 challenge breaks because the API token for your DNS provider was rotated. Renewal fails nightly, into a log nobody reads.
  • The cert renews on disk but the reload never fires, so the process keeps serving the old one. Everything on the machine says "renewed"; every client sees the countdown continue.
  • The load balancer, the CDN, and the origin each have their own cert. Automation covers two of the three.

The common thread: the renewal system believes everything is fine. The only vantage point that can't be fooled is the one your users have — an external client doing a real handshake and reading the certificate that was actually served. That's a monitoring job, not a renewal job.

One alert is not a plan; escalation is

A single "certificate expires in 30 days" email is nearly worthless. At D-30 nothing is urgent, so it gets a mental automation will handle it and an archive. If automation doesn't handle it, there is no second chance.

Deadlines need escalation. okokumo's TLS checks alert at four thresholds — D-30, D-14, D-7, and D-1 — and each tighter threshold fires a fresh alert even though the check is already failing. Internally that's a deliberate oddity: crossing from the 14-day bucket into the 7-day bucket emits a down→down transition purely so the alert dispatcher notifies you again. A monitoring system that alerts once and then goes quiet is politely watching you miss the deadline.

The rhythm matters more than the numbers. D-30 says "check that renewal is configured." D-14 says "renewal has now failed at least once — go look." D-7 says "this is a ticket." D-1 says "this is today's top priority." When the cert renews, the tracker resets, and next cycle starts clean.

Expiry is not the only way a certificate fails

A certificate can be perfectly in-date and still turn away every visitor. The classic is the incomplete chain: your server sends the leaf but not the intermediate. Browsers often paper over this with cached intermediates, so the site works on your machine — while curl, mobile apps, and anything with a fresh trust store gets a hard failure. You find out from a customer, not from your browser.

That's why an expiry check that only reads notAfter is half a check. okokumo's TLS probe does a real handshake with SNI, then verifies the full chain against system roots — and it does the verification manually, so that even when the chain is broken it can still tell you the expiry date alongside the error, instead of just "handshake failed." A check fails if the chain doesn't verify, if the name doesn't match, or if expiry is inside the threshold window. Same probe, three different outages caught.

If you want to see what a probe sees for any host right now, the free TLS checker runs the same inspection code as the scheduled checks — expiry, issuer, chain validity — with no account.

The layer under the certificate: your domain

There's a failure mode one level down that takes the certificate, the website, the API, and your email with it: the domain registration expires. It happens to real companies — the Foursquare (2010) and Microsoft hotmail.co.uk incidents are the famous ones — and it's usually not negligence but a dead credit card on the registrar account, an admin email pointing at an ex-employee, or an ambiguous "who owns renewals" between two teams.

Certificate monitoring won't warn you: the cert stays valid while the domain lapses under it. So okokumo's domain checks watch two things. DNS resolution is the authoritative signal — if the domain stops resolving, the check is down. And expiry comes from RDAP, the structured successor to WHOIS, which most registries expose: the probe reads the registry's own expiration date for your domain and runs it through the same D-30/14/7/1 escalation as certificates. One honest caveat: registries rate-limit RDAP and a few TLDs don't publish expiry at all, so the lookup is best-effort — an RDAP hiccup never fails the check on its own, DNS does.

Why this belongs next to your uptime checks

You could bolt on a separate cert-expiry tool. But an expiring certificate, a broken chain, and a lapsing domain are not a separate category of problem — they're just outages with more notice. They deserve the same treatment as any other check: the same alert channels, the same incident history, the same confirmation logic before anyone gets paged. When the D-7 alert fires, it should arrive where your on-call already looks, not in a fourth dashboard with its own login.

The setup is deliberately boring: add a TLS check on each hostname that terminates TLS (not just the apex — the API subdomain and the CDN have their own certs), add a domain check per registered domain, point the alerts at the channel you already read. Ten minutes, roughly the same flow as your first HTTP check.

Certificate expiry is the one outage that publishes its own date. The only way to be surprised by it is to not be looking.


okokumo is infrastructure monitoring hosted in France — HTTP, heartbeat, TLS and domain checks, probed from two EU regions. TLS and domain checks with escalating expiry alerts are available on every plan, including Free. Try the free TLS checker — no account needed.