What happens when a TLS certificate expires?
A TLS certificate expires when the current date passes the notAfter value in the certificate, and the failure happens before a single byte of HTML is served. Transport Layer Security provides encryption, integrity, and authentication, and a certificate binds a public key to a domain; once that binding is out of date, the client can no longer trust the connection. A command-line client such as curl aborts the handshake with a certificate-expired error, and Chrome replaces the page with a full-screen "Your connection is not private" warning carrying the error NET::ERR_CERT_DATE_INVALID.
Why this matters
Most failures degrade a single route or a single feature. An expired TLS certificate takes down the whole origin, because the browser validates the chain during the TLS handshake, before it has fetched any HTML. Every request fails at the same point: pages, form posts, fetch calls, third-party callbacks, and crawlers. Uptime monitors that only look for an HTTP 200 may still report the site as healthy, which is exactly why an expiry often runs for hours before anyone notices. A visitor who saw the site an hour ago may keep loading it from a cached session while a first-time visitor is rejected, so "it works in my browser" proves nothing about the certificate.
How to fix it
Let's Encrypt's Certbot obtains and renews certificates and stores them under /etc/letsencrypt/live/, and it installs a scheduled task that renews before expiry. A successful renewal does not update the running server, so reload the service so it serves the new file; a renewal that lands on disk while the old certificate stays in memory is a common cause of surprise expiries. If a CDN or load balancer terminates TLS, the certificate must be renewed at that layer, because renewing an origin file cannot update a separate edge certificate. Cloudflare's Universal SSL issues, renews, and deploys a free publicly trusted certificate automatically, which removes the manual step for that tier.
sudo certbot renew --dry-run
sudo systemctl reload nginx
How to verify the fix
Read the certificate the server actually serves, over a fresh connection, not the file on disk. The pipeline below asks OpenSSL for the negotiation details and then prints only the validity window of the leaf certificate. The output lists notBefore and notAfter; treat anything already past notAfter as a live outage and anything close to it as urgent. Repeat the check for every hostname and every address that DNS returns, because a stale node behind a load balancer can make the failure look intermittent.
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
Automated check
The Auditor does not read certificate expiry, so there is no finding for a certificate that is about to lapse. Add an external expiry monitor or read the live dates with the command above, and alert well before notAfter, because a silent renewal failure is the usual cause of an unexpected outage.
Scan your app free →