A certificate-expiry alert should inspect the certificate presented by the public hostname, not only the local certificate file or the last successful renewal job. A renewed file can coexist with an old certificate at the serving endpoint. For each hostname, record the observed expiry and separately verify the hostname and trust chain. If the probe fails, the answer is unknown or broken, not 'no certificate expiring.'
Probe the endpoint visitors reach, with its hostname as SNI
OpenSSL's s_client sends the requested server name with -servername. This matters when one endpoint hosts several names. Replace example.com with a hostname you control and run the probe from a network that can reach its public endpoint. The first command checks the TLS verification result; the second prints the served leaf certificate's expiry. Inspect both outputs and command exit status, including pipeline failure. They answer different questions.
openssl s_client -connect example.com:443 -servername example.com -verify_hostname example.com -verify_return_error </dev/null
set -o pipefail
openssl s_client -connect example.com:443 -servername example.com </dev/null | openssl x509 -noout -enddate -subject -issuerThe enddate is a UTC notAfter value, not a promise of continued availability. A leaf certificate with time remaining can still fail hostname or chain verification, or the endpoint can be unreachable. Conversely, a failed handshake yields no trustworthy expiry reading. OpenSSL's x509 -checkend accepts a number of seconds and returns nonzero if the certificate expires within that window, but use it only after a successful certificate read.
Separate the incident types before alerting
| Observation | What it establishes | Operator response |
|---|---|---|
| Renewal job succeeded | A renewal process reported success, not what the endpoint serves | Probe the public hostname again |
| Served certificate expires soon | This endpoint presented a leaf certificate with a near notAfter | Check renewal and deployment path |
| Handshake, hostname, or trust check failed | The probe cannot confirm usable TLS | Alert as a failure; do not report healthy expiry |
Run the check for each hostname and port that matters. A CDN edge, an origin, and a second region may serve different certificates. Include the observation time, hostname, endpoint, expiry, and verification outcome in the alert. Recheck the served endpoint before claiming a renewal fixed the problem. Make threshold notifications stateful so a daily check does not resend the same 30-day warning every day.
A prompt alone is not a certificate monitor
Our SSL Cert Monitor gallery item formerly asked web_fetch to read certificate expiry, although a page fetch alone does not expose the presented certificate's expiry. Its revised checklist requires an approved TLS-capable runner or equivalent monitoring API, and treats missing probe access as a blocker. It does not install a schedule, implement renewal, or claim a tested deployment. Test one expiring fixture and one unreachable endpoint, then verify that the intended recipient actually receives each distinct alert.
Inspect the SSL Cert Monitor checklist