You renewed the certificate. The file on disk has the new dates. The browser still shows the old one, still expired, still throwing a warning at everyone who visits.
The certificate being renewed and the certificate being served are two different facts, and only the second one reaches your visitors. Something between the new file and the browser is still handing out the old one.
Six places the old certificate hides
Work down this list in order. The first two account for most cases.
| # | Where | How to tell |
|---|---|---|
| 1 | The service never reloaded | The new file is on disk with the right dates, but the running process still holds the old one in memory. Reload or restart the service, not the machine |
| 2 | A CDN or reverse proxy in front | Your origin is perfect and irrelevant. Whatever terminates TLS publicly is what visitors see, and it has its own certificate store |
| 3 | One node in a load balancer pool | Some requests are fine, some are not. This is the maddening intermittent case |
| 4 | IPv6 pointing somewhere else | The AAAA record reaches a different box that nobody updated. Everything looks fine from an IPv4-only network |
| 5 | A second listener on another port | Port 443 renewed, port 8443 or 9001 forgotten, each with its own certificate configuration |
| 6 | Your own TLS session cache | Least likely, easiest to rule out. Test from another network |
Test the address, not the hostname
This is the step that turns guesswork into an answer. A hostname can resolve to several addresses, and they can each be serving something different. Check them individually:
openssl s_client -connect 203.0.113.10:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -dates -subject
Run that against every address the hostname resolves to, IPv4 and IPv6 both. The moment one of them reports the old dates, you have found your machine and the guessing stops.
To get the list of addresses:
dig +short example.com A example.com AAAA
The renewal succeeded and that is the problem
It is worth being clear about why this is so common. Automated renewal tools report success when they have obtained and written a certificate. That is genuinely all they promised to do.
Getting that file loaded by every process, on every node, behind every proxy that terminates TLS for the name is a separate job, and on anything more complicated than a single server it is usually a separate piece of automation that somebody has to have written. When people say “auto-renewal is broken,” the renewal is nearly always fine and the deployment step is what never existed.
Confirm it is actually fixed
Do not trust the absence of a browser warning on your own machine, since your session may be cached and your route may not be everyone’s route.
Check each address again with the command above, and confirm the dates, the subject, and the alternative names are the ones you intended. If a name is missing from the new certificate you have swapped one outage for another.
More on this in certificate expiry, revocation, and deployment, and in fixing and retesting for the wider verification loop.