Site Still Shows an Expired Certificate After Renewing?

Farouk Ben. - Founder at OdownFarouk Ben.()
Site Still Shows an Expired Certificate After Renewing? - Odown - uptime monitoring and status page

Why Does My Site Still Show an Expired Certificate After Renewing? The Four Places It Lives

Renewing a certificate and serving a certificate are two different operations, and the gap between them is where this problem lives. If your site still shows expired after a successful renewal, the new certificate almost certainly exists on disk. Something between that file and the visitor is still presenting the old one.

This article works through the four places a certificate lives between issuance and a browser, in the order you should check them, so you can find which link in the chain is stale. It covers the reload step that catches most people, the layers in front of your server that hold their own copies, and the smaller number of cases where the problem really is on the visitor's side.

The four places a certificate lives

Between issuance and a green padlock, a certificate exists in four distinct places, and a renewal only updates the first one automatically.

It lives on disk, as the file your ACME client or CA wrote. It lives in your web server's memory, loaded at startup and held until the process reloads. It lives in whatever sits in front of your server, which might be a CDN, a load balancer, a reverse proxy, or a hosting control panel, each of which terminates TLS with its own copy. And it lives, briefly, in the visitor's browser and operating system, which cache connection details for a short period.

Work them in that order, because the failure is far more likely at the top of the list than the bottom. The single most common cause by a wide margin is the second one, and it is almost never the fourth.

The reload step, and why it is missed

Your web server reads the certificate file when it starts. After that it holds the parsed certificate in memory and does not check the file again. Writing a new file into place changes nothing about what is being served until the process is told to re-read it.

This is why renewal automation almost always includes a deploy hook, and why a renewal can report complete success while the site continues serving the expired certificate. Certbot's own tooling supports this through deploy hooks, either a deploy-hook flag on the renewal or a script in the renewal-hooks deploy directory, and the standard content of that script is simply reloading the web server. A certificate renewed but never reloaded is the quiet cause behind the specific complaint that renewal said success and the site is still broken.

Confirming it takes a moment. Compare the expiry date in the certificate file on disk against the expiry date the server is actually presenting on the wire, which is exactly what an SSL checker reads during the handshake. If the file is new and the wire is old, you have found it, and a reload resolves it. If both are old, the renewal did not actually produce a new certificate and the problem is upstream, which our post on certbot renewal failures covers.

A related version of the same mistake is renewing into the wrong path. If your server configuration points at one directory and your client writes to another, both files exist, both are correct, and the wrong one is being served. This is common after a migration, a rename, or a change of ACME client, and it produces exactly the same symptom.

The layers in front of your server

If your origin is serving the new certificate and visitors still see the old one, something in front of your origin is terminating TLS with its own copy.

A CDN or reverse proxy is the usual suspect. When a proxy terminates TLS at the edge, the certificate a visitor sees is the edge's certificate, not your origin's, and renewing at the origin does nothing to the edge. Some proxies manage their own certificates automatically and some require you to upload one, and in the second case renewal is a two step process that people frequently only do the first half of.

Load balancers behave the same way and add a variant worth knowing about, which is partial deployment. If a certificate is updated on some nodes and not others, visitors get the new certificate or the old one depending on which node answers them. The symptom is maddening and diagnostic: the site is fine when you check and broken when a colleague checks, and both of you are right. Any time a certificate problem appears intermittent, uneven deployment across a pool is the first thing to suspect.

When it really is the visitor's side

This is the least likely cause and the first one people reach for, so it is worth bounding.

Browsers and operating systems do cache TLS session information, and a browser that has an open connection or a cached session can briefly behave as though nothing changed. The window is short, typically minutes rather than hours, and it applies only to clients that connected before the change. A fully closed browser, a private window, or a different device will not be affected.

That gives you a clean test. If the site is fine in a private window on your phone over mobile data, and broken in your usual browser, the certificate is fine and the cache is stale. If it is broken everywhere, including on a device that has never visited the site, the problem is on the server side and no amount of clearing will help.

The one genuinely server-side cause that presents like a client problem is an incomplete chain. If your server sends the leaf certificate without the intermediate, some clients will succeed because they already hold the intermediate from a previous connection, while others fail. That produces the same works-for-me-not-for-you pattern as uneven load balancer deployment, and the fix is to serve the full chain rather than just the leaf. Our guide to common SSL errors covers what each browser warning distinguishes, since the specific message narrows this down considerably.

Common mistakes in fixing a certificate that still shows expired

Assuming renewal means deployment. The web server holds the certificate in memory from startup. Without a reload, a perfectly valid new file on disk changes nothing about what visitors receive.

Clearing browser caches first. It is the least likely cause and it costs you the diagnostic value of a clean test. Check what the server is presenting before touching the client.

Checking only from your own machine. Uneven deployment across load balancer nodes and incomplete certificate chains both produce results that vary by client. One successful check proves one path worked.

Forgetting the CDN or proxy. If something in front terminates TLS, it serves its own certificate. Renewing at the origin does not touch it, and visitors never see the origin's certificate at all.

Renewing into a path the server does not read. After a migration or a client change, the file can be written correctly to a directory nothing is configured to load. Both certificates exist and the wrong one is served.

FAQ

Why does my site still show an expired certificate after renewal?

Most often because the web server has not reloaded. It reads the certificate at startup and keeps it in memory, so a new file on disk is not served until the process re-reads it. A reload usually resolves it immediately.

Do I need to restart my web server after renewing a certificate?

A reload is normally enough and avoids dropping connections, which is why renewal automation typically includes a deploy hook that reloads the server. A full restart works too but is rarely necessary.

Why do some visitors see the new certificate and others see the old one?

Usually uneven deployment across load balancer or CDN nodes, so the answer depends on which node responds. An incomplete certificate chain produces the same pattern, because some clients already hold the missing intermediate and others do not.

Could this be a browser cache problem?

Occasionally, and only for a short window on clients that connected before the change. Test in a private window on a device that has never visited the site. If it works there, it is a client cache. If it fails, the server is serving the old certificate.

Closing thought

The reason this problem is so disorienting is that every individual step reports success. The CA issued the certificate, the client wrote the file, the log says renewed. Nothing failed, and the site is still broken, because renewal and deployment are separate events and only one of them was verified. The habit that removes this entire class of problem is to stop trusting the renewal log and start checking what the server is actually presenting on the wire.

That check is exactly what certificate monitoring does, and Odown runs it on a daily cycle across unlimited SSL monitors on every plan, including the twelve dollar tier, with expiry alerts at 30, 10, and 7 days and custom thresholds available. Because it reads what the host presents rather than what your automation reported, a certificate that renewed successfully and never reached the server shows up as the problem it is rather than the success it claims to be.