SSL certificate expiry monitoring: get an alert before a cert expires
How to check when an SSL certificate expires (openssl, one command), why calendar reminders fail, and how to alert on every domain at 30, 14 and 7 days.
By The Opservo team
An expired SSL certificate is one of the most embarrassing outages you can have: nothing crashed, no code changed, and yet every browser now shows your users a full-page security warning. It’s also one of the most preventable — the expiry date is known weeks in advance. The only failure is not watching it.
Check when a certificate expires: one openssl command
For any live domain, this prints the not-before and not-after dates of the certificate the server actually presents:
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -datesTo check a certificate file instead of an endpoint (internal services, self-signed certs, a cert behind a load balancer that terminates TLS), point x509 at the file:
openssl x509 -noout -dates -in /path/to/cert.pemFor a scriptable yes/no, the -checkend flag takes a number of seconds and exits 1 if the certificate expires inside that window — 2592000 is 30 days:
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -checkend 2592000 || echo "expires within 30 days"Wrap that in a loop over your domains, run it from cron every morning, and pipe a failure to mail or a Slack webhook. That is the whole of a home-made monitor — and it is exactly the kind of script that stops running the day the box it lives on is rebuilt.
Why certs slip through the cracks
- Auto-renewal (Let’s Encrypt/certbot) silently fails — a hook errors, a rate limit hits, DNS changed — and nobody notices until it lapses. Monitor the outcome, not the process.
- A cert is managed somewhere you forgot: an old nginx vhost, a load balancer, an internal admin subdomain.
- The reminder email went to an inbox nobody reads, or the domain was bought by someone who has since left.
The certificates that get missed
- Wildcard certificates — one cert covers many subdomains, so one expiry takes everything down at once.
- Staging and internal services — often self-signed or hand-issued, with no renewal at all.
- Load balancer and CDN certificates — managed in a cloud console, invisible from the server you SSH into.
- Certificates from a private CA for service-to-service mTLS — short lifetimes and no tooling.
- Inbound webhook endpoints where you terminate TLS for a third party.
Alert at 30, 14 and 7 days, not once
A single 30-day warning is better than nothing. A 30-day warning plus a 7-day warning is what actually gets certs renewed in time.
Thirty days out is a calm renewal, or time to discover that auto-renewal has been failing. Fourteen is the reminder. Seven means the renewal pipeline is broken and someone needs to act today. Three alerts to a channel people read beat one email to a shared inbox.
What good SSL monitoring looks like
You want three things: coverage of every HTTPS endpoint you actually serve (not just the ones you remembered to add), a check from outside your network (so you’re testing what real users hit), and a warning with enough lead time to act calmly — ideally escalating as the date approaches.
- Discover certs automatically from the vhosts already on each server, so nothing is missed.
- Check expiry from the cloud, the same way a browser sees it — including intermediate chain problems.
- Alert early (e.g. 14 days), then louder inside 3 days, to Slack/email — not a single email you might miss.
How Opservo handles it
Opservo reads the nginx/apache vhosts on each server and tracks the live SSL expiry of every domain automatically — no manual list to maintain. Add an external HTTPS uptime monitor and it also checks the certificate from outside your network on every run, warning you before it expires (critical inside three days) through whatever channels you’ve set up. You find out with two weeks to spare, not from an angry customer.
Certificates shouldn’t be a source of surprise. Watch them once, everywhere, and forget about them — and if you’re deciding what else deserves an alarm, start with the signals that actually matter.