---
title: Renewed the certificate but the old expiry still shows? How to check with the SSL Expiry Checker
description: Let's Encrypt says the certificate renewed, yet browsers still show the old expiry date. Renewal writes a new file; only the server that loads it serves it, and every hostname can sit on a different server. Here's how to check SSL certificate expiry per hostname with the free SSL Expiry Checker, how to prove which certificate is live, and the openssl commands that compare it with the file on disk.
canonical: https://watchfor.io/blog/how-to-check-ssl-certificate-expiry
---

# Renewed the certificate but the old expiry still shows? How to check with the SSL Expiry Checker

2026-10-04 · WatchFor Team · Guides · guides, ssl, certificates

Let's Encrypt says the certificate renewed, yet browsers still show the old expiry date. Renewal writes a new file; only the server that loads it serves it, and every hostname can sit on a different server. Here's how to check SSL certificate expiry per hostname with the free SSL Expiry Checker, how to prove which certificate is live, and the openssl commands that compare it with the file on disk.

To check when an SSL certificate expires, connect to the hostname on port
443 and read the *not after* date of the certificate the server sends. Do it
for every hostname and port people use: `example.com` and
`www.example.com` can be served by different machines with different
certificates, and a renewal on one of them changes nothing on the other.

The free [SSL Expiry Checker](/ssl-expiry-checker) does that handshake from
a WatchFor probe and shows the days left, the exact *not after* date, the
issuer and the serial number of the certificate that's live. No signup.

## What this tool answers

*How many days are left on the certificate this hostname serves right now?*
Reach for it after a renewal to confirm the new certificate is the one being
served, when a browser or monitoring tool warns about an expiry you thought
was fixed, when you inherit a site and need a list of what expires when, or
before a holiday. The answer comes from the server, not from your
certificate manager's dashboard, which only knows what it issued.

## A real example

### Checking SSL certificate expiry when two hostnames disagree

The classic report: "certbot says it renewed, but the browser still shows
the old date." Often the browser is looking at a different hostname or a
different server than the one that got the new file. To show how common
that split is, we checked both names of one well-known site.

In the [SSL Expiry Checker](/ssl-expiry-checker) we ran `mozilla.org`, then
`www.mozilla.org`, both on port **443**, from the Vilnius probe:

![The SSL Expiry Checker result for mozilla.org:443: 70 days until expiry, VALID, subject mozilla.org, issuer WR3 from Google Trust Services, not before 2026-09-14T09:15:07Z, not after 2026-12-13T10:07:59Z, TLS 1.3, one SAN mozilla.org](/blog/how-to-check-ssl-certificate-expiry-apex.webp)

![The SSL Expiry Checker result for www.mozilla.org:443: 47 days until expiry, VALID, subject www.mozilla.org, issuer YR1 from Let's Encrypt, not before 2026-08-22T02:47:59Z, not after 2026-11-20T02:47:58Z, TLS 1.3, one SAN www.mozilla.org](/blog/how-to-check-ssl-certificate-expiry-www.webp)

Same site, two different certificates:

| | `mozilla.org` | `www.mozilla.org` |
| --- | --- | --- |
| Days left | **70** | **47** |
| Not after | 2026-12-13 10:07:59 UTC | 2026-11-20 02:47:58 UTC |
| Issuer | Google Trust Services (WR3) | Let's Encrypt (YR1) |
| Issued | 2026-09-14 | 2026-08-22 |
| SANs | `mozilla.org` only | `www.mozilla.org` only |

Two CAs, two renewal schedules, and neither certificate covers the other
name. Both are 90-day certificates in good health. But it shows the trap: if
someone renewed the apex certificate and then opened `www`, they'd still see
20 November and conclude the renewal failed.

**The answer:** check the exact hostname the warning is about, then compare
its serial and *not before* with the certificate you just renewed. If they
differ, the new certificate exists but isn't served there. The usual reasons
and fixes:

- **The server never reloaded.** nginx, Apache and HAProxy read certificates
  at start-up. Reload after renewal: certbot runs a hook only if you set one,
  e.g. `certbot renew --deploy-hook "systemctl reload nginx"`.
- **Another machine terminates TLS.** A load balancer, CDN or ingress
  controller serves its own copy. Upload or re-import the new certificate
  there, or let it manage the certificate itself.
- **A different hostname, a different certificate.** As above. Renew each
  one, or issue one certificate that lists both names.
- **One server out of several.** Behind a load balancer, one node may still
  serve the old file. Check each node by IP with the hostname as SNI.

## How to read the results

| What you see | What it means |
| --- | --- |
| **Days until expiry** | Whole days left until *not after*. Green from 45 days, amber 14–44, red under 14. |
| **VALID / INVALID** | VALID means trusted chain, matching name and inside the dates. An expired certificate fails the handshake and shows INVALID with `ssl_handshake_failed`. |
| **host:port** | What was checked. Repeat for each hostname and port. |
| **Subject / SANs** | Which names this certificate covers. |
| **Issuer / Issuer org** | Who signed it. A change of CA after renewal is a quick sign the new certificate is live. |
| **Not before** | When it was issued. Today's date right after a renewal means the new one is served. |
| **Not after** | The expiry moment, in UTC. |
| **Serial** | Unique per certificate, shown in decimal. `openssl` prints it in hex; they're the same number. |

Amber isn't automatically a problem. For a 90-day certificate, current
certbot renews when less than a third of the lifetime is left, about 30
days, so a healthy Let's Encrypt certificate sits in amber for part of every
cycle. Under 14 days, something has stopped renewing.

## More ways to use it

- **Build an expiry list.** Run every public hostname and port (`443`, `465`,
  `993`, `8443`) once and note *not after*; it's often the first time anyone
  sees them side by side.
- **Before a CA migration.** Note the current issuer and dates, switch, then
  confirm the issuer changed on every name.
- **Wildcards.** One wildcard certificate often sits on many servers. Check a
  few subdomains on different machines: they should all show the same
  serial.
- **Check what a CDN serves.** The certificate visitors see is the CDN's,
  not your origin's; check the origin separately by its own hostname or IP
  with SNI.

## Tips and gotchas

- **Lifetimes are getting shorter.** Public certificates may be valid for at
  most 200 days now, 100 days from March 2027 and 47 days from March 2029.
  Manual renewals won't keep up; see
  [47-day SSL certificates](/blog/47-day-ssl-certificates).
- **Once it has expired, there's nothing to read.** The handshake fails, the
  checker shows INVALID, and the date comes from the command line below.
- **The probe sees one front end.** Behind GeoDNS or anycast, other regions
  may hit a server with a different certificate.
- **Dates are in UTC.** A certificate that expires at 02:47 UTC is gone
  before the start of the working day in the Americas.

## Check it from the command line too

Print the issuer, expiry and serial each hostname serves:

```bash
for h in mozilla.org www.mozilla.org; do
  echo | openssl s_client -connect $h:443 -servername $h 2>/dev/null \
    | openssl x509 -noout -issuer -enddate -serial
done
```

```text
issuer=C=US, O=Google Trust Services, CN=WR3
notAfter=Dec 13 10:07:59 2026 GMT
serial=12B3DDD5EEAAD1D010655E4192CD7D5D
issuer=C=US, O=Let's Encrypt, CN=YR1
notAfter=Nov 20 02:47:58 2026 GMT
serial=0507FF684E11E418C556924322DB676DAD3C
```

`0x12B3DDD5…7D5D` is `24860024423791182954756840211990019421` in decimal,
the serial the checker showed. On your server, run the same `x509` command
on the renewed file and compare:

```bash
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -enddate -serial
```

Different serials mean the server is still serving the old certificate.
For scripts and cron jobs, `-checkend` takes seconds and exits non-zero when
the certificate expires within that window:

```bash
echo | openssl s_client -connect www.mozilla.org:443 -servername www.mozilla.org 2>/dev/null \
  | openssl x509 -noout -checkend 2592000 && echo "more than 30 days left"
```

```text
Certificate will not expire
more than 30 days left
```

## Keep watching it

A renewal that silently stops is the most preventable outage there is. An
[SSL monitor](/ssl-monitoring) checks each hostname and port on a schedule
and its **Certificate Expiry** rule opens a warning incident when fewer than
14 days remain (raise it to 30 if your automation renews late), with an
optional critical level that counts as downtime and pages on-call. HTTP
monitors record days until expiry too.
[How to never get caught by an expired SSL certificate](/blog/ssl-certificate-expiry)
covers the rest of the setup.

## FAQ

**How do I check when my SSL certificate expires?**
Run the SSL Expiry Checker on the hostname, click the padlock in your
browser and open the certificate details, or run
`openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -enddate`.

**Why does my browser still show the old certificate after renewal?**
The server hasn't loaded the new file (reload it), another machine such as a
load balancer or CDN serves its own copy, or you're looking at a hostname
covered by a different certificate. Compare the serial the server sends with
the renewed file.

**How many days before expiry should I renew an SSL certificate?**
With automation, let it renew at about a third of the lifetime left (30 days
for a 90-day certificate) and alert when fewer than 14 days remain, which
means automation has failed. How certificates fit into HTTPS is in
[How HTTPS works](/blog/how-https-works).

---

Canonical page: https://watchfor.io/blog/how-to-check-ssl-certificate-expiry · All articles: https://watchfor.io/blog/all.md · Site guide: https://watchfor.io/llms.txt
