An expired certificate is one of the few failures where the browser itself stands between you and your customer. Not a slow page, not a broken image — a full-screen red warning telling people your site is unsafe, with a button that is deliberately hard to find. Card payments stop. Mobile apps that pin or validate strictly stop. Webhooks from your suppliers stop, silently, because software does not click through warnings.
The frustrating part is that in most of these outages the certificate was renewed. It was issued days earlier, it is sitting in the right directory, and the automation reported success. What never happened was the last step: getting the running process to use it.
What a browser is actually checking
A TLS handshake sends the client a chain, not a certificate. Three things have to line up:
- The leaf — your certificate, naming your hostnames in its Subject Alternative Names, valid between two dates.
- One or more intermediates — the CA's signing certificates. Your server has to send these; they are not magic.
- A root — which the client already trusts, from the trust store built into the OS, browser or runtime.
If the leaf has expired, every client refuses. If an intermediate is missing, behaviour splits in a way that causes real confusion: browsers often repair the chain themselves by fetching the missing certificate from the URL in the leaf's AIA extension, so the site looks perfectly fine to you, while curl, Java clients, older Android and many payment gateways fail outright. "It works in Chrome" is not a test result.
The five ways renewal quietly fails
1. The cron ran, the service did not reload
Web servers read certificates into memory at start-up. A new file on disk changes nothing until nginx, Apache, HAProxy or the application is reloaded. ACME clients support deploy hooks for exactly this reason, and the hook is the part that gets forgotten — or gets written for the service you ran last year.
2. Renewed on one node
Behind a load balancer, renewal that runs on a single node leaves the other members of the pool serving the old certificate. The result is an intermittent outage: reload, and the error goes away; reload again, and it comes back. It survives testing precisely because it is not deterministic.
3. The edge is still holding the old one
With a CDN or reverse proxy in front, the certificate the public sees is the edge's, not your origin's. Updating the origin changes nothing for visitors, and updating the edge changes nothing for anyone connecting directly. Both have to be checked, from outside.
4. The wrong file was deployed
ACME clients typically write several files: cert.pem (leaf only), chain.pem (intermediates) and fullchain.pem (both). Point your server at cert.pem and you have shipped the missing-intermediate problem described above — which will look fine in your browser and break a partner's integration next week.
5. A name is missing
Certificates cover the names listed in them. Add www, a new marketing subdomain or a regional hostname without adding it to the renewal configuration, and that name is served a certificate that does not match — the same interstitial, for one part of the estate only.
What breaks without it
- The website, behind a browser warning that most visitors will not click past.
- APIs and webhooks. Clients fail closed. Suppliers retry for a while and then stop; some disable the endpoint after repeated failures.
- Mail over TLS. If the certificate on your MX host is expired or misnamed, senders enforcing an MTA-STS policy will defer or reject rather than downgrade. See Making SMTP encryption something you can rely on.
- Mobile apps that validate strictly or pin — an app-store release cycle away from a fix.
- Trust. A browser saying "attackers might be trying to steal your information" is a worse first impression than a 500 page.
How to check it in 30 seconds
Run the SSL certificate check. It connects the way a client would and reports the days remaining, the issuer, the Subject Alternative Names, whether the chain your server actually sent validates, and which TLS versions are accepted. From a terminal, the equivalent:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \ | openssl x509 -noout -dates -subject -ext subjectAltName
Two habits make this useful. Test every hostname, not the apex only — www, the API host, the mail host, the status page. And test from outside your network, where your visitors are, not from a machine that talks to the origin directly.
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates reads the file on disk. That is the file the automation wrote, not the certificate the server is presenting — and the gap between those two is the outage this article is about.Fix it
- Give every renewal a deploy hook that reloads the service, and test it by forcing a renewal in staging rather than waiting for the real one.
- Serve
fullchain.pem, nevercert.pem, and confirm the chain validates for a non-browser client. - Check every node behind the load balancer, and the edge as well as the origin.
- Keep the SAN list and your DNS in sync: every hostname that resolves and terminates TLS needs to be on a certificate.
- Publish a CAA record so only your intended CA can issue for the domain —
dig +short CAA example.comshould not come back empty. - Alert on days remaining as observed from the internet, not on the success of the renewal job.
- Make sure the domain itself cannot lapse underneath the certificate: the outage nobody plans for.
Then keep it that way
Add the hostname to StatusDNS and the certificate is re-inspected on a schedule from outside your network — the same view a customer gets. We record the expiry date, the issuer, the names on the certificate and whether the chain the server sends validates, and we alert at 30, 14, 7, 3 and 1 days before expiry, plus immediately if the chain stops validating or the certificate stops matching the hostname. Alerts go by email, Slack or webhook.
We do not issue or renew certificates, and we never need access to your server. The job here is narrower and, on the day it matters, more useful: telling you that what the internet can see is not what your automation believes it deployed.