MeatButton

SSL Certificate Expired: Why Your Site Says "Not Secure" and How to Fix It

For anyone seeing "Your connection is not private" on their site

You open your own website and the browser hits you with a full-screen warning: "Your connection is not private" or "NET::ERR_CERT_DATE_INVALID." Visitors can't get to your site at all. Some browsers won't even let them click through. Your site is effectively offline.

Here's what happened: your SSL certificate expired. And until it's renewed, every visitor sees that warning instead of your site.

What's an SSL certificate and why does it matter?

An SSL certificate (technically TLS, but everyone still says SSL) does two things:

Certificates don't last forever. They have expiration dates. When a certificate expires, the browser treats it like no certificate at all — and throws up the scary warning page.

Why most people don't see this coming

Most websites use Let's Encrypt, a free service that issues SSL certificates. Let's Encrypt certificates are valid for 90 days — much shorter than the old paid certificates that lasted a year or more.

The idea is that renewal is automatic. You set up a tool called certbot that runs in the background, checks if your certificate is close to expiring, and renews it before it does. When this works, you never think about SSL again.

When it breaks, you don't find out until visitors start seeing the warning. There's no alarm. No email that gets through. Your certificate just quietly expires, and your site goes dark.

The most common reasons auto-renewal stops working

1. The renewal timer was never set up

When you first got your certificate — or when the AI helped you set up your server — certbot may have been used to get the initial certificate but nobody set up the scheduled task to renew it. The certificate worked for 90 days, and then it just... stopped.

This is extremely common on servers set up with AI assistance. The AI gets you the certificate in the moment, but doesn't always wire up the ongoing renewal.

2. Your web server is blocking the renewal challenge

When certbot tries to renew, Let's Encrypt needs to verify you still control the domain. It does this by placing a temporary file on your server and then trying to fetch it over port 80 (plain HTTP).

The problem: many Nginx and Apache configs redirect ALL traffic from port 80 to port 443 (HTTPS). That redirect intercepts Let's Encrypt's verification request before certbot can answer it. The renewal fails silently.

This is the sneaky one. Everything looks correct. The config is "right" in theory. But the redirect is too aggressive and blocks the one thing that needs plain HTTP to work.

3. Your domain's DNS changed

If you changed hosting providers, pointed your domain at a different IP address, or switched from one DNS service to another, the Let's Encrypt verification request might be going to the wrong server — one that doesn't have certbot running on it.

4. A firewall is blocking port 80

Some server setups have firewall rules that block incoming connections on port 80, since "everything should be HTTPS anyway." That's fine for regular visitors who get redirected, but it kills the Let's Encrypt verification process.

5. Certbot itself is outdated or broken

Certbot gets updated regularly. Old versions can develop incompatibilities with Let's Encrypt's servers. If your server has been running untouched for a year or two, the installed version of certbot might simply not work anymore.

What to try

If you're comfortable with the command line — or willing to try — here's the diagnostic sequence:

Test if renewal would work

sudo certbot renew --dry-run

This simulates a renewal without actually changing anything. If it fails, the error message usually tells you why. Read the full output — the important part is often buried in the middle.

Check if the renewal timer exists

systemctl list-timers | grep certbot

You should see a line for certbot.timer with a next-run time. If there's nothing there, auto-renewal was never set up. You can enable it with:

sudo systemctl enable --now certbot.timer

Check the certbot logs

sudo cat /var/log/letsencrypt/letsencrypt.log

This log shows every renewal attempt and why it succeeded or failed. Look for the most recent entries.

Force a renewal right now

sudo certbot renew --force-renewal

This skips waiting for the certificate to be close to expiry and tries to renew immediately. If your site is already down, this is what you want — assuming the underlying problem is fixed first.

Reload your web server after renewal

sudo systemctl reload nginx

Or sudo systemctl reload apache2 if you're running Apache. A renewed certificate doesn't take effect until the web server picks it up.

Why AI is bad at this specific problem

SSL renewal failures are deeply specific to your server. The fix depends on:

The AI doesn't know any of this. It gives you generic commands that work on a default setup. But if your setup isn't default — and most aren't, especially if AI helped build it in the first place — the generic commands either don't work or make things worse.

A common example: the AI tells you to run certbot --nginx, but your certificate was originally set up with --webroot. Now you have two different certbot configurations fighting each other, and neither one works.

The urgency factor

Most server problems are annoying but survivable. This one is different. Every minute your SSL certificate is expired, every single visitor sees a security warning and leaves. Google Chrome won't even let them proceed without clicking through multiple warnings. On mobile, many browsers block the site entirely.

Search engines will also start flagging your site. If the certificate stays expired for more than a day or two, your search rankings take a hit that takes weeks to recover from.

This is a "right now" problem, not a "get to it this weekend" problem.

Your site is down right now and the clock is ticking

Every visitor is seeing a security warning instead of your site. Press the MeatButton and a real expert will SSH into your server, figure out why certbot isn't renewing, and fix it. First one's free.

Get MeatButton