A Let's Encrypt certificate renews itself every sixty days without anyone noticing - until a change made months earlier blocks the validation. The failure is silent; the first sign is usually a browser warning.
See the real expiry
echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates
The three blockers
- A redirect that catches the validation request. The check is a plain HTTP request to
/.well-known/acme-challenge/. A blanket http-to-https rule that also redirects that path breaks it. - The DNS record moved. The domain now points somewhere else, so the check reaches a server that has never heard of the challenge.
- A firewall or a WAF blocking port 80. Closing 80 because "everything is https now" closes the door renewal comes through.
Let the challenge through
location ^~ /.well-known/acme-challenge/ {
root /var/www/html;
try_files =404;
}
That block goes before the redirect rule, so the challenge is answered and everything else still goes to https.
Force one renewal and watch it
certbot renew --dry-run
The dry run does the whole exchange without spending a rate limit. If it passes, the real one will.
Let's Encrypt rate-limits repeated failures. Fix the cause and use --dry-run to test; retrying the real command in a loop will lock you out for hours.
On EGPHP hosting renewal is handled for you and this page is for a VPS you run yourself. If a managed certificate ever shows a warning, it is a support ticket, not a config change.