Know what manages the certificate
Start by listing the certificates certbot manages. The listing shows each certificate's name, domains, expiry date and the paths of the certificate and key. If your certificate is not listed, certbot does not manage it, and the cause is elsewhere: another client, a panel or a purchased certificate. If it is listed, the expiry date tells you how much time remains, and the renewal configuration file for that name records how it was issued, including the authenticator, such as the standalone or webroot method, and any hooks. Do not edit that file casually; certbot has a command for changing renewal options that tests against staging before saving.
- List certificates before diagnosing anything.
- Note the authenticator recorded for each name.
- Check the names on the certificate match every hostname you serve.
The dry run is the real test
Running the renewal command with the dry-run option contacts Let's Encrypt's staging server and obtains test certificates that are not saved. It checks whether future renewals will succeed with your current configuration, and the pre- and post-hooks run during it, though deploy hooks do not unless you ask for them. Exit status is non-zero only when a renewal attempt fails, and it is zero when nothing was due, so a quiet success does not prove a renewal happened. Use the dry run after any change to DNS, the web server, the firewall or redirects, and use the deploy hook for actions that must follow a real renewal.
- A passing dry run is evidence, not a guarantee.
- Add the option to run deploy hooks when you want to test the reload too.
- Use staging for every experiment so you cannot hit production limits.
What schedules it
Renewal only happens if something runs the command. Most packaged installs add a systemd timer or a cron entry, and the documentation says to look in the cron files or list the timers to find out. If you cannot find one, nothing renews the certificate, and a manual run earlier in the year explains why it worked once. Running the command twice a day is normal and safe, since it renews only certificates that are due; certbot also suggests a random delay so servers do not all call at the same moment. After Certbot 4.0.0 the trigger is less than a third of the certificate's lifetime remaining, where earlier versions used a fixed 30 days, so older advice about 30 days is out of date for current versions.
- Look at the timers and the cron directories.
- A missing schedule is a common cause of a certificate that expired quietly.
- Do not rely on an expiry reminder email; check the schedule itself.
A renewed file is not a renewed site
Renewal writes new files, but a web server that read the old certificate at start keeps serving it until it reloads. A deploy hook solves this by reloading the web server only after a successful renewal. Hooks placed in the renewal hooks directory run automatically in alphabetical order, and a failing hook does not stop the renewal attempt. Verify the result the way a visitor sees it: ask the server for its certificate from outside and read the expiry date. If the date has not moved, the file renewed but the server did not reload. Keep the hook small and make it reload, not restart, the named web server.
- Test the hook with the dry-run option that includes deploy hooks.
- Check the served certificate from outside, not the file on disk.
- A reload is gentler than a restart for a busy server.
Add an alert that does not depend on the server
Let's Encrypt stopped sending expiry emails in 2025, so the server's own renewal is no longer backed by a reminder. An outside check that reads the certificate and warns you well before expiry catches a broken schedule, a firewall change or a failed reload. The fixed renewal repair job finds the cause on a server you run, fixes it, proves it with the dry run and the served certificate, and tests an outside alert. It does not promise future renewals will succeed.
Sources and limits
- Certbot user guide: renewal Checked 2026-10-11.
- certbot renew only renews certificates that are due, and --dry-run uses the staging server and saves nothing.
- Most installs have a scheduled task; check cron files or systemctl list-timers.
- Deploy hooks run only after a successful renewal; hooks in the renewal-hooks directories run in alphabetical order.
- As of Certbot 4.0.0 renewal is attempted when less than a third of the lifetime remains; earlier versions used 30 days.
- Let's Encrypt FAQ Checked 2026-10-11.
- Standard certificates last 90 days and the FAQ recommends renewing every 60 days.
- Let's Encrypt: ending expiration emails Checked 2026-10-11.
- Let's Encrypt stopped sending expiration notification emails on 4 June 2025 and points to third-party monitoring instead.