Almost every outage is a surprise. Certificate expiry is not. The date is printed inside the certificate, served to every visitor, and readable months in advance. It is the one failure that tells you exactly when it will happen, and sites still go dark because of it every week.
The reason is rarely that nobody knew certificates expire. It is that the renewal was automated, the automation broke quietly, and nothing was watching the one number that would have shown it.
Watch the served certificate, not the renewal job
The important distinction: a renewal job succeeding is not the same as a visitor getting a valid certificate. Between the two sit a reload that did not happen, a proxy holding the old file in memory, a second load balancer that never got the new bundle, and a CDN with its own copy.
So the check that matters connects to the hostname the way a browser does, completes the handshake, and reads the expiry from the certificate the server actually presented. That is what a relay19 TLS check does: it dials the host, looks at what came back, and counts the days left.
If your renewal cron writes to disk and nothing reloads nginx, the job log says success and the check says twelve days left, then eleven, then ten. Only one of those two is telling the truth.
How far ahead to warn
Every relay19 HTTPS monitor watches its own certificate, with a warning threshold of 14 days by default. About once a day it connects, reads the expiry from the certificate the server presented, and opens a certificate incident when fewer than that many days remain. It is a warning that arrives before the outage rather than during it, through whichever channels that monitor already uses, and it never counts against uptime: the site is still up. The standalone TLS check does the same for hosts that are not websites, such as mail servers or custom ports.
Thirty is the number worth setting on anything customer facing. It is roughly one billing cycle and one holiday, so the warning survives the person who owns it being away.
If you want a second, louder alert closer to the wire, add a TLS check on the same hostname with minimum days valid set to 7 and route it to a different channel: the first one is a task, the second one is an incident.
The instinct to set 90 days is worth resisting. Let’s Encrypt issues for 90 days and renews at 30, so a 90 day threshold fails on every healthy certificate you own, every cycle. An alert that is normal is an alert people learn to close without reading, and that habit is what makes the real one invisible.
The failures an expiry countdown will not catch
Days remaining is the headline number, not the whole story. A handshake can fail for several reasons while the leaf certificate is still perfectly valid:
- A broken chain. The leaf is fine, but the server stopped sending the intermediate. Desktop browsers often paper over this with cached intermediates while curl, mobile apps and payment webhooks fail outright.
- The wrong hostname. A renewal that dropped a name from the SAN list.
The certificate is valid, just not for
www. - A revoked or expired intermediate. Rare, and out of your hands, but it takes you down all the same.
- A protocol floor moving. A partner turning off TLS 1.0 and 1.1 on their side, or your own stack tightening ciphers and cutting off an old client.
This is why a TLS check and an HTTP check on the same hostname are not redundant. The TLS check answers “is the certificate healthy and how long do we have”, the HTTP check answers “does a real request succeed right now”. A chain problem shows up in the second one first.
Cover the hosts nobody visits
The site everyone loads is usually the safest one, because a broken certificate there is noticed within minutes. The dangerous ones are the hosts with no human traffic:
api.example.com machines only, no one would see a browser warning
smtp.example.com mail stops, silently, at 00:00 UTC
staging.example.com breaks, gets ignored, then is needed urgently
vpn.example.com discovered by the whole team at the same moment
Mail is the cruellest of these. An expired certificate on an SMTP host does not produce an error page. It produces mail that quietly stops being delivered, sometimes for days, until someone asks why they never got the invoice.
Mail hosts need one extra thought, because a TLS check speaks implicit TLS. On port 465 that is exactly right, and the countdown works the same as it does on 443. Ports 25 and 587 negotiate with STARTTLS after a plaintext greeting, so cover those with an SMTP check, which holds a real SMTP conversation and tells you the server is answering, and let the check on 465 watch the certificate.
Make the countdown visible
Certificate expiry is the rare failure where monitoring is genuinely preventive rather than reactive. You are not waiting to detect an outage, you are watching a number go down and stepping in before it reaches zero.
Add a TLS check for every hostname that terminates its own TLS, including the ones no browser ever opens. The quickstart covers adding one, and every plan includes TLS checks, including the free one.