Site AI Auditby Internet Solutions

How to Automate SSL Renewal With Certbot (and Verify It Works)

September 24, 20268 min readSecurity & SSL
How to Automate SSL Renewal With Certbot (and Verify It Works)

Short answer: Certbot renews Let’s Encrypt certificates automatically when a scheduled job runs certbot renew, usually twice a day via a systemd timer or cron. It renews certificates that are within about 30 days of expiry. To make renewal reliable, confirm the timer exists, test with certbot renew --dry-run, add a deploy hook that reloads your web server (and any other service using the certificate), use DNS validation if HTTP validation is blocked by a CDN or firewall, and monitor the live certificate from outside so a silent failure is caught weeks before expiry.

Certbot is the most widely used tool for obtaining free certificates from Let’s Encrypt on servers you manage yourself. Getting the first certificate takes a minute. Keeping renewals working for years, through server upgrades, DNS changes and configuration edits, is where problems appear. This guide covers how Certbot’s renewal works, how to configure it properly on a typical Linux server, and how to verify that it keeps working.

How Certbot renewal works

When you first obtain a certificate, Certbot stores its settings – domains, validation method, web server plugin, hooks – in a renewal configuration file under /etc/letsencrypt/renewal/. Renewal is then a separate step:

  1. A scheduler runs certbot renew, typically twice a day.
  2. Certbot checks every certificate it manages. Those not yet close to expiry are skipped.
  3. For certificates due for renewal (by default, when fewer than about 30 days remain), Certbot repeats validation with the stored settings and obtains a new certificate.
  4. New files are written, and the symlinks in /etc/letsencrypt/live/<name>/ are updated to point to them.
  5. Hooks run – for example reloading the web server so it starts using the new certificate.

Your web server should always reference the files in the live directory – fullchain.pem and privkey.pem – never copies elsewhere, so it automatically picks up renewed certificates after a reload.

Step 1: Check the scheduler

Most installation methods set up scheduling automatically. Check which applies to your server:

systemctl list-timers | grep -i certbot     # systemd timer (common with distro packages)
snap services certbot                       # snap installations
grep -ri certbot /etc/cron* /var/spool/cron 2>/dev/null   # cron entries

If nothing appears, add a schedule. A simple cron entry that runs twice a day with a random delay to spread load:

0 */12 * * * root sleep $((RANDOM % 3600)) && certbot renew -q

Avoid having two schedulers (for example a snap timer and an old cron job) at once; it is harmless but confusing when troubleshooting.

Step 2: Test with a dry run

Run:

sudo certbot renew --dry-run

This performs the full renewal process against Let’s Encrypt’s staging environment without replacing your real certificates. Every certificate should report success. If one fails, the output explains why – most often a validation problem. Run a dry run after any change to DNS, firewall, web server configuration, CDN or redirects.

Step 3: Reload services with a deploy hook

A renewed certificate on disk does nothing until the services using it reload. Certbot’s web server plugins (--nginx, --apache) usually handle the web server, but other services – a mail server, a separate reverse proxy, a load balancer, a Node.js application – do not reload automatically. Add a deploy hook, which runs only when a certificate was actually renewed:

sudo sh -c 'printf "#!/bin/sh\nsystemctl reload nginx\nsystemctl reload postfix\n" > /etc/letsencrypt/renewal-hooks/deploy/reload.sh'
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload.sh

Scripts in /etc/letsencrypt/renewal-hooks/deploy/ run for every renewed certificate. You can also set a hook per certificate with --deploy-hook. If a service needs the certificate copied to a different location or format, do the copy in the same hook, then reload.

Step 4: Choose the right validation method

HTTP validation (webroot or web server plugin)

Let’s Encrypt fetches a token from http://yourdomain/.well-known/acme-challenge/. This requires port 80 to be reachable and the path not to be blocked or redirected elsewhere. Common breakers: firewalls closing port 80, redirect rules sending everything to another host, security rules blocking hidden folders, and maintenance pages.

DNS validation

You prove control by creating a TXT record under _acme-challenge.yourdomain. Required for wildcard certificates, and useful when the server is not reachable from the internet or sits behind a CDN that interferes with HTTP validation. For automatic renewal you need a Certbot DNS plugin for your DNS provider and an API credential, stored with restrictive permissions.

The Let’s Encrypt documentation on challenge types explains the trade-offs in detail.

Common renewal failures and fixes

Symptom in logsLikely causeFix
Timeout or connection refused during validationPort 80 blocked or DNS points elsewhereOpen port 80 or switch to DNS validation
404 or unauthorized for the challenge URLRedirects, rewrite rules or wrong webrootExclude /.well-known/acme-challenge/ from rules; correct webroot path
CAA record prevents issuanceCAA record does not list Let’s EncryptAdd letsencrypt.org to CAA
Too many failed authorizations or certificatesRepeated failing attempts hit rate limitsFix the cause using –dry-run, then wait for the limit window
Renewal succeeded but site shows old dateService not reloaded, or config points to a copyDeploy hook; reference the live directory
No renewal attempts at allTimer or cron missing after server rebuildRestore the scheduler and run a dry run

Renewal logs are in /var/log/letsencrypt/; the most recent file shows the last attempt in detail.

Verify from the outside

A successful log entry is not proof that visitors receive a valid certificate. After a renewal, and periodically, check what the server actually presents:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates -issuer

Compare the dates with sudo certbot certificates, which lists what Certbot has on disk. If they differ, a service was not reloaded or another server answers for the domain. Check every hostname and every server behind a load balancer.

Then add external monitoring with an alert when a certificate has fewer than two or three weeks left. With Certbot renewing at about 30 days before expiry, such an alert means renewal has failed at least several times – and you still have time to fix it calmly.

Several servers, one domain

When a domain is served by more than one machine – two web servers behind a load balancer, or a web server plus a separate mail server – running Certbot independently on each can cause trouble. HTTP validation may land on a server that did not start the request, and each server ends up with a different certificate and key. Better options:

Whichever you choose, test every server from outside after the first automated renewal, because this is where one machine quietly keeps the old certificate.

Keeping it working through server changes

How Site AI Audit helps

Site AI Audit checks the certificate your visitors actually receive – validity, expiry date and the HTTP to HTTPS redirect – at the start of every audit. The Monitor plan checks weekly and sends an e-mail alert when something breaks, including a certificate nearing expiry; Business and Agency plans check SSL daily. That outside view is exactly what catches a Certbot renewal that fails silently. See the plans.

Related reading

The bottom line

Certbot makes renewal automatic, but only if the scheduler runs, validation keeps working and services reload after renewal. Check the timer, test with a dry run after every infrastructure change, add a deploy hook for every service that uses the certificate, choose DNS validation when HTTP is not reliable, and monitor the live certificate from outside. Then renewals really do take care of themselves.

FAQ

How often does Certbot renew certificates?

The scheduled job typically runs twice a day, but Certbot only renews certificates that are close to expiry, by default when fewer than about 30 days remain. With 90-day certificates, that means roughly every 60 days.

Do I need to restart my web server after renewal?

A reload is needed so the server loads the new certificate. Certbot’s Nginx and Apache plugins usually do this, but other services need a deploy hook that reloads them.

Why does certbot renew –dry-run work but real renewal fails?

Differences are rare but can come from rate limits, a CAA record, or changes made between the dry run and the renewal. Check the latest log in /var/log/letsencrypt/ for the exact error.

Can Certbot renew certificates behind Cloudflare or another CDN?

Yes. HTTP validation often works through the proxy if the challenge path is not blocked, and DNS validation with the provider’s plugin works regardless of the proxy.

What happens if renewal fails for a few days?

Nothing visible at first, because renewal starts about 30 days before expiry. Certbot keeps retrying, so you have time to fix the cause – provided monitoring tells you it is failing.

#HTTPS#SSL certificate#TLS
Check your own website — free.What to fix on your website — and where to start.
Start free

More from the blog

All articles →
Internet Solutions

More from our team

Built by Internet Solutions. Try the rest of our products — each one saves you time in a different way.

internet-solutions.net ↗
Site AI Audit
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.