SSL/TLS Certificates. Don't Get Caught Expired
How certs work in 2026, why auto-renew quietly fails, and how to sleep through Let's Encrypt rotations.
SSL/TLS in 2026
"SSL" technically refers to a protocol family deprecated in 2015. What everyone calls SSL today is actually TLS. Transport Layer Security. The terms are used interchangeably. TLS 1.3 (2018) is the current version; TLS 1.2 is still acceptable for legacy clients.
A TLS certificate does two things: it asserts that the server is who it claims to be (via a trusted certificate authority signing the cert), and it provides the public key used to bootstrap an encrypted session. Every browser bakes in a list of trusted CAs; certificates signed by anyone outside that list trigger security warnings.
Why active monitoring still matters
Auto-renewal made expired certs a "solved problem" from 2017 onwards. And yet, every week, major sites still go down because their cert expired. Why?
- Renewals run on a schedule. If the scheduler stops running, certs expire silently.
- Validation methods break, port 80 gets firewalled, DNS records get cleaned up, the renewal hits a CA rate limit.
- Server config changes mean the renewed cert lands in the right directory but the running web server isn't restarted to pick it up.
- The original installer left the system, nobody knows the renewal config exists, the timer runs but the cert isn't installed where the server reads it from.
The only thing that catches all four is checking the actual cert served by the actual server, externally, from outside the network, the same way a customer's browser would. That's why certbot renew --dry-run isn't enough; it only verifies that certbot thinks renewal works.
How a TLS handshake works
- Client opens TCP connection to port 443.
- Client sends ClientHello with supported TLS versions, cipher suites, and SNI (which hostname it wants to talk to).
- Server picks a TLS version and cipher, sends its certificate chain in ServerHello.
- Client validates the cert chain against trusted CAs.
- Client and server exchange key material; in TLS 1.3 this happens in the same flight as ServerHello, saving a round trip.
- Encrypted application data begins.
From a monitoring perspective, what matters is what the server presents in step 3 and what the client validates in step 4.
What a thorough SSL check actually verifies
- Connection succeeds on port 443. (Refused / timeout = your monitoring stopped right there.)
- Cert is valid for the hostname. Both the Common Name (CN) and Subject Alternative Names (SAN) are checked. Modern browsers ignore CN and only look at SAN, so SAN must include the hostname.
- Cert is not yet expired and not expired. The
notBeforeandnotAfterfields define the validity window. - Cert is signed by a trusted CA. Self-signed certs and certs from internal CAs will fail in browsers (not necessarily flagged by all monitoring tools).
- TLS version is acceptable. 1.0 and 1.1 should be disabled; 1.2 acceptable; 1.3 ideal.
Expiry alerting thresholds
The window industry consensus has settled on:
- > 30 days: pass. No action needed.
- 14–30 days: warning. Verify renewal is configured and working. If you're using Let's Encrypt, this is when auto-renewal would normally kick in, if it hasn't, something is wrong.
- < 14 days: critical. Manual intervention required. Renewal has clearly failed.
- Expired: emergency. Customers see browser warnings. Fix immediately.
Let's Encrypt specific gotchas
Most TLS certs in 2026 are Let's Encrypt. The renewal failure modes specific to LE:
- Rate limits. 50 certs per registered domain per week. If you have many subdomains and they all renew on the same day, you can hit it.
- HTTP-01 validation requires port 80. If you firewalled port 80 because "we only use HTTPS," renewals will fail. Either keep port 80 open for ACME challenges or switch to DNS-01.
- DNS-01 requires DNS API access. If your DNS provider doesn't expose an API, DNS-01 isn't an option without a CNAME delegation.
- Renewal hooks didn't run. Your nginx is still serving the old cert because the post-renewal hook that runs
systemctl reload nginxdidn't fire.
Self-hosted vs CDN-managed certs
If your traffic goes through Cloudflare, Fastly, or another CDN, the public-facing cert is managed by the CDN and renews automatically without action. Your origin server still needs a cert for the CDN→origin leg, but that one rarely changes and can be a long-validity internal cert.
What's worth checking either way: that the public-facing cert (whoever issues it) is valid, not expired, covers your hostname, and the TLS version is current.
Monitoring strategy
- Check externally, at least daily.
- Check every hostname separately if you use mixed cert strategies (wildcard + per-host).
- Alert at 30 days, escalate at 14 days.
- Verify the cert covers the hostname, not just that it exists.
- Verify TLS version, outdated TLS is a silent compliance issue.
DomainsDoc does all of this hourly. We connect to your domain on 443, complete the TLS handshake, extract the cert, and alert you if expiry drops below 30 days, if the cert doesn't cover the domain you registered, or if the TLS version is below 1.2. Combined with HTTP uptime and DNS monitoring, you get one alert when your site has a problem, not three separate ones from three separate tools.
Frequently asked questions
How early should I get alerted about SSL expiration?
My certbot says auto-renew is configured. Why did my cert still expire?
What's the difference between TLS 1.2 and TLS 1.3? Should I care?
Do I need to monitor SSL for subdomains separately?
What does "certificate does not cover this domain" mean?
Inspect any HTTPS host's certificate: expiry, issuer, SANs, and TLS version, instantly.
Continuous SPF, DKIM, DMARC, blacklist, SSL, and uptime checks. Alerts the moment something breaks.