The cert that expired at midnight and nobody knew until 9 AM
The cert expired at midnight. For nine hours, the customer portal returned a TLS handshake error to anyone who tried to load it.
Not the main site — that was on a different cert, separately managed. The customer portal lived on a subdomain set up years earlier by someone who no longer worked there. The cert was an old Let’s Encrypt one that hadn’t been converted to auto-renewal. It expired on a Thursday night.
The on-call engineer found it at 9:07 AM Friday, when the first customer complaint came through during standup.
The fix took 4 minutes. The downtime was 9 hours.
The thing about cert expiry
You can get every other piece of your monitoring right and still miss a cert. Uptime monitors check if your site is responding. They tell you when the cert is already expired and the site is throwing errors. By then it’s too late — the nine hours have already happened.
The useful interval is 30 days before. 14 days. 7 days. 1 day. When the cert is about to expire and you still have time to renew it before anything breaks.
Nobody I know has a clean answer for this. Registrar emails go to spam. Auto-renewal works great until it fails silently. Internal tooling breaks when Python versions change or webhooks rotate.
What I wanted
A service that sends me one email per expiring cert. Sent 30 days before, 14 days before, 7 days before, 1 day before. Not a dashboard. Not a service I have to maintain. An email at the right time.
I also wanted it to check the TLS cert directly from the wire — by actually connecting to the server and reading the certificate’s notAfter field. This catches the edge case where the cert is technically not expired but the chain is broken (root rotation, missing intermediate).
And WHOIS for domain expiry, because the domain registrar and the TLS cert are separate problems and I’ve had both fail.
CertWatch
A cron that runs every day and checks every domain in your list for: domain expiry via WHOIS, TLS cert expiry (direct wire check), chain validity, and DNS health. One email per cert per milestone — 30 days, 14 days, 7 days, 1 day. No dashboard. The only action is: when the email arrives, renew the thing.
Free tier: 5 domains. Starter: $5/month for 100 domains. Pro: $15/month for 1,000 domains + Slack/Teams webhook + two recipients.
The model is built around the pivot moment: 5 important domains on free, and when the sixth one appears, $5/month is a trivial decision.
certwatch.app — limited beta, put your email in.
The customer portal incident cost more than 4 minutes when you count the postmortem, the retro, and the explanation to the customer. Whatever CertWatch costs per month, the math closes on the first expiry it prevents.