Certificate expiry is the most boring outage there is. Everyone knows it will happen, it is entirely predictable, and it still takes down shops, booking forms and mail servers every week. The cause is almost never “nobody renewed it”. The cause is “the thing that was supposed to renew it stopped, and nothing told us”.
The recovery steps are in a separate post on what to do when a certificate has already expired. This one is about the other half: knowing early enough that you never need that post.
Why renewals fail
Let’s Encrypt certificates last 90 days, and the industry is moving to shorter lifetimes in stages through 2029. Shorter lifetimes mean more renewals, and every renewal is a chance for something to have changed since the last one. The usual reasons:
- The challenge cannot be answered. HTTP-01 needs port 80 reachable. A firewall change, a new redirect rule or a CDN in front breaks it.
- DNS moved. The name now points to a different host, and the old server’s certbot is renewing a certificate nobody sees.
- The timer vanished. A server rebuild, a migration or a package change removed the cron entry or
certbot.timer. - Renewed but not reloaded. The new file is on disk; nginx, a load balancer or a mail server still holds the old one in memory.
- A forgotten hostname.
api.,staging.,mail.andshop.often have their own certificate and nobody’s name on the ticket. - A commercial certificate whose renewal email goes to an employee who left.
- Rate limits. A broken retry loop uses up the weekly allowance, and the real renewal is refused.
Step 1: build the hostname inventory
You cannot monitor what you have not listed. For each client domain, collect every hostname that serves TLS: the website, www, the API, the admin panel, the mail server, the staging site, the shop subdomain.
Certificate transparency logs are public and find hostnames people forget. This lists names that ever had a certificate under a domain:
curl -s 'https://crt.sh/?q=%25.example.com&output=json' | jq -r '.[].name_value' | sort -u
Remove names that no longer exist, then add the survivors to a spreadsheet with three columns: hostname, who owns it, how it renews (certbot, hosting panel, CDN, commercial CA).
Step 2: check expiry yourself, in one line
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate
For a script, -checkend turns it into a yes or no. This exits with status 1 if the certificate expires within 30 days (2,592,000 seconds):
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -checkend 2592000
Loop it over your inventory:
for h in example.com www.example.com api.example.com; do
echo | openssl s_client -servername "$h" -connect "$h:443" 2>/dev/null \
| openssl x509 -noout -checkend 2592000 > /dev/null || echo "RENEW SOON: $h"
done
Mail and other TLS services are separate certificates on separate ports. Use -starttls smtp -connect mail.example.com:587 for SMTP submission, or -connect mail.example.com:993 for IMAPS. The free SSL checker shows the issuer, the expiry date and whether the chain is valid for any HTTPS host without installing anything.
A cron job that runs the loop is better than nothing. It is worse than a monitor, because it shares a server, a mail setup and an attention span with the thing it is supposed to watch.
Step 3: let something outside watch the certificate your visitors get
An external monitor connects the way a visitor does, with the right server name, and reads the certificate that is actually served. That catches the “renewed on disk, not reloaded” case that a file-based check misses.
In Tenium, SSL and domain expiry monitors start on the Starter plan ($7 a month). They alert at 30, 14 and 3 days before expiry, and also on a certificate that has already expired, is untrusted, is self-signed or does not match the hostname. Every HTTPS check also records the expiry date it sees, so the date is on the monitor page and in the monthly report.
Set the alert to a contact someone reads. Email works on every plan; Telegram and Slack start on Starter. For a client account, alert yourself first and the client later, so you can fix it before they see it.
Edge cases that catch people out
- Cloudflare and other proxies. Visitors see the proxy’s certificate, which renews itself. The origin has its own certificate, and that one can expire silently and cause 525 or 526 errors. Monitor the public name, and add a check on the origin if you can reach it directly.
- Wildcards and multi-name certificates. One certificate covering
*.example.comand the bare domain is one renewal for many hostnames. Monitor each important hostname anyway, because a deployment can leave a single one on an old copy. - Staging with a self-signed certificate. Do not alert on it as if it were production. Keep staging monitors separate, or leave them out.
- An internal certificate authority. A public monitor cannot validate a private chain; expect an “untrusted” result and monitor those names from inside.
- Mail and API ports. A certificate on port 465 or 993 expires independently of the website, and the first sign is mail that stops arriving.
Step 4: do not forget the domain
The certificate and the domain are two different clocks. A domain that lapses takes the site, the mail and the certificate down together, and the first sign is often a registrar parking page. Check the date with the domain expiry tool, which reads the registry through RDAP, and monitor it the same way as certificates. Tenium’s domain monitoring alerts at the same 30, 14 and 3 day steps.
For every domain you manage:
- turn on auto-renew at the registrar and check that the card on file is valid;
- send registrar emails to a shared mailbox, not to a person;
- enable the registrar lock to avoid transfers by mistake;
- note who pays: agency or client. This is the dispute that follows every lapse.
Step 5: put the dates on the client report
A line in the monthly report that reads “SSL certificate valid, 61 days remaining; domain renews in 212 days” does two things. The client sees something concrete for the care-plan fee, and you glance at the dates once a month. On the Agency plan the report is generated per client; on Pro there is one branded report. See client reports.
A renewal checklist you can reuse
- All hostnames listed, including mail and staging
- Each hostname has an owner and a known renewal method
- Auto-renewal tested once with
certbot renew --dry-runor the host’s equivalent - A reload hook that restarts the web server after renewal
- An external expiry monitor on every production hostname
- Domain auto-renew on, payment method current, registrar mail to a shared inbox
- Expiry dates on the monthly report
If you compare monitoring tools mainly for certificate checks, the Tenium vs Oh Dear comparison covers a tool that is built around certificates and broken-link crawling, and says where it is stronger.
Frequently asked questions
How early should I get an SSL expiry alert?
Tenium warns 30, 14 and 3 days before expiry. Thirty days is enough to fix a broken renewal during working hours, 14 days is the second chance, and 3 days means someone must act today. Domain expiry uses the same three steps.
My certificate renews automatically. Do I still need monitoring?
Yes. Automation fails quietly: a firewall closes port 80, DNS moves to another host, a timer is deleted, a load balancer is not reloaded. Monitoring reads the certificate your visitors actually receive, which is the only thing that matters.
Does SSL monitoring also cover the domain name?
They are separate clocks. A certificate expiring does not affect the domain, and an expired domain takes the site and its certificate down with it. Monitor both. Tenium checks domain expiry through RDAP and alerts at the same 30, 14 and 3 day steps.
Which plan includes SSL and domain expiry monitoring?
SSL and domain expiry monitors start on the Starter plan ($7 a month). The Free plan has HTTP, keyword, ping and port checks.
Can I check expiry from the command line?
Yes. Run openssl s_client with -servername, pipe it to openssl x509 and add -checkend with a number of seconds. It exits with 1 if the certificate expires inside that window, which makes it easy to script.
Related
Related Tenium pages
Monitor your first site free
30 monitors free, checks from 2 regions, no card. SSL and domain expiry from $7 a month.