Guide

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.

8 min read·Updated May 25, 2026
TL;DR
Modern SSL is almost solved. Let's Encrypt renews automatically, browsers enforce HTTPS, and TLS 1.3 is widely available. The remaining failure mode is silent: auto-renewal breaks for a hundred reasons and nobody notices until the cert expires and customers see security warnings. Monitor externally.

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

  1. Client opens TCP connection to port 443.
  2. Client sends ClientHello with supported TLS versions, cipher suites, and SNI (which hostname it wants to talk to).
  3. Server picks a TLS version and cipher, sends its certificate chain in ServerHello.
  4. Client validates the cert chain against trusted CAs.
  5. Client and server exchange key material; in TLS 1.3 this happens in the same flight as ServerHello, saving a round trip.
  6. 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 notBefore and notAfter fields 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.
Watch out
Let's Encrypt certs are 90 days by default. Auto-renewal is supposed to trigger at 30 days remaining. So you should never see a Let's Encrypt cert with 14 days left, if you do, your renewal is broken.

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 nginx didn'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?
Industry standard is 30 days, with critical alerts at 14 days. Anything shorter and you have no buffer for unexpected issues; anything longer and you train yourself to ignore the alerts. DomainsDoc warns at 30 days and goes critical at 14.
My certbot says auto-renew is configured. Why did my cert still expire?
The five usual culprits: (1) The renewal cron/timer isn't actually running, check `systemctl status certbot.timer`. (2) Port 80 is blocked, so HTTP-01 validation fails. (3) DNS validation pointed at a domain that's since changed. (4) The certbot package was upgraded and changed its renewal config path. (5) Disk full, renewal silently failed. Always monitor the cert externally, not just `certbot renew --dry-run`.
What's the difference between TLS 1.2 and TLS 1.3? Should I care?
TLS 1.3 is faster (one round-trip handshake instead of two), more secure (removes broken cipher suites), and supported by every modern browser. TLS 1.0 and 1.1 are deprecated and should be off. TLS 1.2 is acceptable for legacy clients. Aim for TLS 1.3 with TLS 1.2 as fallback.
Do I need to monitor SSL for subdomains separately?
Yes if they use different certificates. Wildcard certs cover one level (*.example.com covers api.example.com but not deep.api.example.com). Multi-domain (SAN) certs cover specific listed names. If a subdomain has its own cert, monitor it separately.
What does "certificate does not cover this domain" mean?
The certificate served by the server was issued for a different hostname than the one you connected to. Common causes: (1) you're connecting to the wrong server (load balancer misconfiguration); (2) the cert was for the old domain after a rename; (3) SNI (Server Name Indication) isn't configured, so the server returns its default cert. All three are deliverability blockers in browsers.
Try it now
SSL Certificate Checker

Inspect any HTTPS host's certificate: expiry, issuer, SANs, and TLS version, instantly.

Open tool
Stop reading. Start monitoring.

Continuous SPF, DKIM, DMARC, blacklist, SSL, and uptime checks. Alerts the moment something breaks.

Start free
Keep reading