# error: certificate has expired: certbot renewal automation fix

## TL;DR

Certbot was installed but the renewal never ran or never reloaded the service, so the cert expired. Fix it now with a forced renew and a reload, then make renewal automatic and monitored: a timer plus a deploy hook plus an expiry alert. Certs expire on schedule; renewals must be automatic.

```text
error: certificate has expired (certbot-managed host)
```

## Steps

1. Renew now: certbot renew --force-renewal, then reload the web server so it picks up the new cert.
   Expected: The site serves a valid cert.

2. Check why auto-renewal failed: systemctl status certbot.timer (or the cron job), and read the last renewal logs.
   Expected: You find the broken timer, the failed challenge, or the missing hook.

3. Fix the root cause: open port 80 for http-01 challenges or fix the dns-01 credentials, and add a --deploy-hook that reloads the server.
   Expected: Renewals complete and take effect.

4. Test with certbot renew --dry-run.
   Expected: The dry run succeeds end to end.

5. Add expiry monitoring: alert at 30 and 7 days before expiry, independent of certbot.
   Expected: The next failure pages before users notice.

## When to use

- a certbot-managed cert expired
- renewal timers exist but the cert is old
- the server serves the old cert after renewal

## When not to use

- certbot was never installed (install it first)
- the cert is from a different CA (different renewal path)
- the challenge type cannot work here (switch challenge types deliberately)

## Tool compatibility

- certbot
- Let's Encrypt
- nginx/Apache

## Variant phrasings

- "certificate expired certbot renewal"
- "certbot renew not working"
- "certbot timer failed"

## Why it happens

Certbot's renew is not magic: it needs a working timer, a reachable challenge path, and a hook that reloads the server. Any of the three missing means the cert quietly expires on its 90-day schedule. The expiry is the most predictable outage in infrastructure, and it still happens constantly.

## Edge cases

- the deploy hook is the forgotten piece; renewal without reload serves the old cert
- rate limits punish repeated --force-renewal; fix the cause, then force once
- wildcard certs need dns-01; http-01 cannot issue them

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_I13jftqYBkw5fqU4L5ZA2g
