How to monitor SSL certificate expiry (and why 30 days is the wrong first alert)

Published 15 Sep 2026 · Updated 15 Sep 2026

Why an expired certificate still takes a site down

A certificate carries a "not after" date. Past it, every client that checks the chain treats the connection as untrusted, and almost every client checks. Three things break in a predictable order.

Browsers refuse. Chrome, Firefox and Safari show a full-page warning with the date in it. On a site that sends HSTS the browser hides the "proceed anyway" link, so a visitor cannot click through at all. Your own site looks like a phishing page until the certificate is replaced.

APIs fail closed. A client library that verifies TLS throws on the handshake, before a single byte of your response is read. Retries do not help, and the error on the calling side names a certificate, not your service, so the engineer on the other end starts by blaming their own code.

Mail queues. A receiving mail server with an expired certificate still answers, but a sender that enforces TLS (MTA-STS in enforce mode, or a strict outbound policy) refuses to hand over the message and keeps it in a queue. Senders that use TLS opportunistically deliver anyway, so the failure is partial: some mail arrives, some sits for days, and nobody notices until a bounce comes back.

None of these failures is gradual. The certificate is fine at 23:59 and the service is gone at 00:00, which is why the date has to be watched ahead of time, not discovered from a symptom.

The ladder: what a 30-day first alert misses

Most certificate reminders default to one alert, 30 days out. On a certificate bought for a year that is reasonable: it gives you a month to order a new one. On an automated certificate it is nearly useless.

A Let's Encrypt certificate lives 90 days and is meant to renew at 60, with 30 days left. A single alert at 30 days therefore fires on the very day renewal is due. If renewal succeeds, the alert was noise. If it fails, the alert looks exactly like the noise from every other cycle. Either way it tells you nothing new.

What you want instead is a ladder. hostnag's alert policy defaults to 30, 14, 7, 3, 1 days before expiry, and inside the last window the warning repeats every day. Read it like this:

  • 30 days: a look. On a 90-day certificate this is the renewal date; on a one-year certificate it is the time to start the paperwork.
  • 14 days: renewal has been failing for two weeks. The automation, the DNS challenge, a rate limit or the account is broken, and it will not fix itself.
  • 7 days: act today. Renew by hand if you have to.
  • 3 and 1 days, then daily: nobody should be able to say they were not told.

Each rung is a separate alert, so a certificate that quietly failed to renew climbs through all of them rather than surfacing once and vanishing. The thresholds are set per group: hand-renewed one-year certificates can start at 60 days while automated ones start at 14.

Public certificate lifetimes are getting shorter, which sharpens the point: the browser root programmes cap new public certificates at 200 days from March 2026, 100 days from March 2027 and 47 days from March 2029. At 47 days a 30-day alert fires before the certificate is halfway through its life. The ladder still works; the single reminder does not.

What to check beyond the date

Expiry is the failure you can put on a calendar. Four others arrive without warning, and a certificate check that only reads the date misses all of them.

The chain. A server has to send the leaf certificate and every intermediate that links it to a trusted root. Miss one and the site works in the browser you tested with, which cached the intermediate weeks ago, and fails for a fresh install, a curl on a build machine or a mail server that has never seen it. hostnag validates the chain from outside on every run and raises an invalid alert when it stops linking.

The hostname. A certificate covers the names in its Subject Alternative Name list and nothing else. A renamed host, a new subdomain pointed at an old load balancer, or a wildcard that does not reach one level deeper all produce a valid, unexpired certificate that does not cover the address you serve. hostnag checks that the name it connected to is on the list.

The issuer. A certificate that suddenly comes from a different authority is worth a look every time. Sometimes it is planned: a CDN switched providers, or the automation moved to another authority. Sometimes it is not, and a certificate you did not order is the first sign that DNS or a hosting account has been taken over. hostnag records the issuer on each run and sends a change alert with the old and new issuer names when they differ.

The fingerprint. Every renewal produces a new certificate with a new fingerprint, so a change is not by itself a problem. What it gives you is a timestamp: the moment a new certificate went live on the address you watch. Set the policy to notify on change and you get a note when a renewal lands, the only positive confirmation that the automation worked, and a note when something you did not schedule swaps the certificate.

Certificates on other ports

The web server's certificate is the one people remember and renew. The others sit on services set up once and left alone.

Mail is the usual case. A submission server takes a plain connection on port 587 and upgrades it with STARTTLS; IMAP does the same on 143 and POP3 on 110. A checker that opens a TLS handshake directly on those ports gets nothing back, because the server is waiting for a plain hello first. hostnag's certificate monitor takes a STARTTLS setting for SMTP, IMAP, POP3 and PostgreSQL (port 5432), speaks the protocol's opening lines, then reads the certificate the server presents.

Everything else answers with TLS straight away on its own port: IMAPS on 993, SMTPS on 465, LDAPS on 636, a VPN gateway on 443 or a port of its own, a database behind a TLS proxy. Add each as its own monitor with the port set. The certificate on the VPN gateway is the one you cannot fix from home once it expires.

Certificates no scanner reaches

Some certificates are never served to the internet: an internal certificate authority for hosts on a private network, client certificates for mutual TLS, code-signing certificates, S/MIME certificates in a mailbox. No outside check can see them, and they expire just the same.

hostnag handles these with a reported certificate. You paste the certificate, or a scheduled task posts it, in PEM or DER form (capped at 64 KB) to a URL minted for that monitor. hostnag parses it once and judges it every day against the same thresholds as a served certificate, without ever connecting to anything. The Beacon script can post the file on a schedule, so a renewed certificate is reported without anyone remembering to. The details are in monitoring private PKI and code-signing certificates.

How often to check

A certificate's expiry date changes once per renewal, so an hourly check and a daily check reach the same conclusion about the date. hostnag runs a certificate monitor at least every 1440 minutes on the Free plan, which is once a day, and lets you shorten that to every 60 minutes on Pro and every 15 minutes on Business.

The shorter interval is not for the date. It is for the change alerts: a swapped issuer or a broken chain is worth knowing about within the hour, not the next morning.

Check one by hand

To see exactly what a client sees, openssl prints the certificate's subject, issuer, expiry and the names it covers. The second command is the STARTTLS form for a mail server.

openssl s_client -connect example.com:443 -servername example.com \
  </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -enddate -ext subjectAltName

openssl s_client -starttls smtp -connect mail.example.com:587 \
  </dev/null 2>/dev/null | openssl x509 -noout -enddate

The -servername flag matters: a server hosting several names picks its certificate by SNI, and without it you may be shown a default that your visitors never get. An incomplete chain shows as a verify error near the top of the output; that is the error a fresh client will hit.

Check it now, then watch it

Check it now: paste a host into the SSL checker to see its days left, chain and hostname match from outside, with no account.

Watch it for good: certificate monitoring checks every certificate you name on its schedule, climbs the ladder as expiry approaches, and tells you when the chain, the name or the issuer changes.

Watch this for good.

Start free