Linux Admin

Test Certbot renewal with a dry run

Prove certificates will renew before you get emailed about expiry.

10 min read Beginner Updated 9 Jun 2026

Step-by-step guide

Work through each section in order. Stop when your issue is resolved — you do not need every step for every situation.

Warning

Certbot dry-run still contacts Let's Encrypt staging infrastructure — do not hammer it in loops. Fix nginx/apache config and DNS before expiry; dry-run failure today means real renewal failure in two weeks.

What you will achieve

Validate Let's Encrypt certificate auto-renewal on Ubuntu or Debian with certbot renew --dry-run — catch nginx plugin errors, firewall blocks, and DNS issues before certificates expire.

1) Confirm certbot is installed

certbot --version
dpkg -l | grep certbot

Install if missing:

sudo apt install certbot python3-certbot-nginx
# or python3-certbot-apache

2) List current certificates

sudo certbot certificates

Note domain names, expiry dates, and certificate paths under /etc/letsencrypt/live/.

3) Run renewal dry-run

sudo certbot renew --dry-run

Simulates renewal for all certificates near expiry. Success ends with a message that dry run passed. Failure shows which vhost or challenge broke — read the full output, not just the last line.

4) Check systemd timer (auto-renewal)

systemctl list-timers | grep certbot
systemctl status certbot.timer

Ubuntu packages enable certbot.timer — twice-daily renewal attempts. Timer active plus dry-run pass equals peace of mind.

5) Common dry-run failures

  • Connection refused on port 80 — nginx/apache not running or UFW blocking
  • 404 on /.well-known/acme-challenge/ — wrong webroot or missing location block
  • DNS problem — A/AAAA record does not point to this server
  • Rate limit — too many failed attempts; wait or use staging for tests
sudo ufw status
sudo nginx -t
curl -I http://example.com/.well-known/acme-challenge/test

6) Test nginx plugin specifically

sudo certbot renew --dry-run --cert-name example.com

Targets one certificate. Useful on multi-domain servers where one vhost misbehaves.

7) Manual hook verification

sudo certbot renew --dry-run --deploy-hook 'systemctl reload nginx'

Deploy hooks run only on successful renewal — dry-run validates hook syntax without reloading unless certbot simulates success.

8) Schedule proactive checks

Run dry-run monthly via cron or monitoring — expiry emails from Let's Encrypt are a last resort, not your primary alert.

sudo certbot renew --dry-run 2>&1 | tee /var/log/certbot-dryrun-$(date +%F).log

Verify

sudo certbot renew --dry-run
echo $?

Exit code 0 and log message confirming simulated renewal succeeded. Check cert expiry remains in the future: sudo certbot certificates.

Related guides

certbot lets encrypt ssl