“Certificate has expired”: what it means and how to fix it
Every HTTPS certificate has a use-by date. When the date has passed, or your device thinks it has, the connection is refused to protect you from a possible impostor.
The messages you might see
| Where | Wording |
|---|---|
| Chrome / Edge | NET::ERR_CERT_DATE_INVALID, “Your connection is not private” |
| Firefox | SEC_ERROR_EXPIRED_CERTIFICATE |
| Node.js / npm | CERT_HAS_EXPIRED, “certificate has expired” |
| Python (requests, urllib) | SSLCertVerificationError: certificate verify failed: certificate has expired |
| curl / git | SSL certificate problem: certificate has expired |
Step 1: find out whose problem it is
Open the same address on another device or network. If it fails everywhere, the site’s certificate has expired and only the site owner can fix it. If it works elsewhere, the problem is on your machine. To read the dates directly:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates -issuer -subject
notAfter is the expiry. If it is in the future but you still get the error, keep reading. (Certificates are just Base64-wrapped data; paste a PEM block into What is this? to see what it is.)
Step 2: the usual causes on your side
- Your clock is wrong. A device whose date is years off (flat CMOS battery, a fresh virtual machine, a phone set manually) sees every certificate as expired or not yet valid. Turn on automatic time. On Linux,
timedatectlshows whether time is synced. Compare your clock with the current Unix time. - An old root certificate. Certificates chain up to a root your device trusts. When an old root expires, devices that never got the newer one fail even though the site is fine. The best-known case was Let’s Encrypt’s old root expiring in September 2021, which broke older Android phones, macOS, curl and Python installs. Update the operating system or the CA bundle (
sudo update-ca-certificates,pip install -U certifi, update Node). - A corporate proxy or antivirus that inspects HTTPS re-signs pages with its own certificate. If that certificate expired, every site fails at once. That is for the IT team or the antivirus settings.
Step 3: if it’s your site
- Let’s Encrypt / certbot: run
sudo certbot renew, then reload the web server (sudo systemctl reload nginx). Test the automatic renewal withsudo certbot renew --dry-run; a failing timer is the usual reason it lapsed. - Renewed but still expired? The server is still serving the old file. Reload or restart it, check the path in its config, and make sure you deploy the full chain, not just the site certificate.
- Behind a CDN: the visitor sees the CDN’s certificate, but the CDN checks yours on the origin. An expired origin certificate shows up as a 526 on Cloudflare (see 502 Bad Gateway and the 520–526 family).
- Set a calendar reminder or a monitor that alerts about 14 days before
notAfter. Public certificates are getting shorter lives, so automation matters more every year.
Why not just turn verification off?
curl -k, NODE_TLS_REJECT_UNAUTHORIZED=0, verify=False and git config http.sslVerify false do make the error go away, but they also accept a forged certificate from anyone in the middle, and they tend to stay in code long after the emergency. Use them for a one-off test at most, never in production.
Getting wrong version number instead? That error happens before any certificate is sent: see SSL wrong version number.
Seeing unable to get local issuer certificate or self signed certificate in certificate chain instead? The dates are fine but the chain can’t be followed to a root you trust: see unable to get local issuer certificate.
Related
Cloudflare Error 525 · Cloudflare Error 526 · TypeError: fetch failed (Node) · self-signed certificate in certificate chain · WebSocket connection failed (wss)
Questions
How do I check when an SSL certificate expires?
Run: echo | openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -dates. The notAfter line is the expiry date. Browsers also show it when you click the padlock and open the certificate details.
Why does my computer say every certificate has expired?
Almost always a wrong system clock. If your device thinks it is a different year, every certificate looks invalid. Turn on automatic date and time and try again.
Is it safe to proceed past an expired certificate warning?
Not for anything involving passwords or payments. The warning means the browser can't confirm it is talking to the real site. On a site you own, renew the certificate instead.
Why does certbot say the certificate was renewed but the site still shows the old one?
The web server keeps the old certificate in memory until it reloads. Run sudo systemctl reload nginx (or apache2), and check its config points at the live fullchain file.
Published .