Security & SSL

Let's Encrypt Not Renewing Automatically: Causes and Fix

If your Let's Encrypt certificate expired without self-renewing, here are the most common causes and how to fix them step by step.

Close-up of a steel padlock on a mesh fence, symbolizing protection and security.

If Let's Encrypt is not renewing your certificate automatically, the cause is almost always one of three things: the cron job (or systemd timer) that calls certbot renew is not active, the server can't respond to the domain validation challenge, or a recent change to your Apache/nginx configuration broke the validation path.

This guide covers each cause with a specific diagnosis and fix.

How Let's Encrypt Automatic Renewal Works

Let's Encrypt issues certificates valid for 90 days. Certbot (the official client) is designed to attempt renewal when fewer than 30 days of validity remain. To do this, it installs a scheduled task during setup:

  • systemd timer (modern distributions): certbot.timer runs twice per day.
  • cron job (older systems or manual installs): a line in /etc/cron.d/certbot or the system crontab.

If either of these mechanisms fails silently — or if the validation process fails when it does run — the certificate will expire without warning (except for the email alerts Let's Encrypt sends at 20 and 7 days before expiry).

Diagnosis: Identifying Why It's Not Renewing

1. Check That the Timer/Cron Is Active

On systems using systemd:

systemctl status certbot.timer

The status should be active (waiting). If it's missing or inactive:

systemctl enable --now certbot.timer

On cron-based systems, check:

cat /etc/cron.d/certbot

You should see something like:

0 */12 * * * root certbot -q renew

If that file doesn't exist, create it or add the line to the system crontab.

2. Run a Dry-Run Renewal

Instead of waiting for the next automatic cycle, simulate the renewal to see if it fails:

certbot renew --dry-run

This command doesn't modify any real certificate — it just verifies the process would succeed. Any error that appears here is exactly what's blocking automatic renewal.

3. Review Certbot Logs

cat /var/log/letsencrypt/letsencrypt.log

Look for lines containing ERROR or FAILED. The most common messages are:

  • Connection refused or Timeout — the server isn't reachable from the internet on port 80.
  • 404 Not Found on /.well-known/acme-challenge/ — the validation directory is blocked.
  • DNS problem: NXDOMAIN — the domain doesn't resolve or the IP recently changed.

Most Common Causes and Fixes

Port 80 Blocked or Redirected Before Validation

Let's Encrypt's HTTP-01 challenge needs to reach http://yourdomain.com/.well-known/acme-challenge/ from its validation servers. If you have a rule in .htaccess or Apache that redirects all HTTP traffic to HTTPS before certbot can respond, validation fails.

Fix: exclude the validation path from the redirect:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Modern certbot (≥ 0.28) handles this automatically when using the --apache or --nginx plugin. If you installed certbot with --webroot, you manage this exclusion manually.

Firewall Blocking Port 80

Even if your site serves only HTTPS, Let's Encrypt's HTTP-01 validation needs port 80 open (it doesn't need to serve full content, just respond to the challenge file). Check:

curl -I http://yourdomain.com/.well-known/acme-challenge/test

If you get Connection refused or a timeout, check your iptables, firewalld, or hosting provider firewall rules. Quick fix:

firewall-cmd --permanent --add-service=http
firewall-cmd --reload

Alternatively, switch to the DNS-01 validation method if you can't open port 80 — it's more advanced but works without port 80.

Domain Name or DNS Recently Changed

If you migrated the domain to a new server or updated DNS records and propagation hasn't completed, Let's Encrypt won't be able to verify domain ownership. Confirm from an external tool that the domain points to the correct IP before attempting renewal again.

Outdated Version of Certbot

Very old versions of certbot may fail against Let's Encrypt's updated API. On snap-based installs (the current recommended method):

snap refresh certbot

For pip or system package installs, update through the appropriate package manager.

Conflicts with a Control Panel (cPanel, Plesk, DirectAdmin)

If you use shared hosting with cPanel or Plesk, these panels manage Let's Encrypt through their own tools (AutoSSL in cPanel, Let's Encrypt SSL in Plesk). If the panel tool is active and you also installed certbot manually, they can conflict. In this case:

  • In cPanel: go to Security → SSL/TLS → AutoSSL and check for reported validation errors. The AutoSSL log is at /var/cpanel/logs/autossl/.
  • In Plesk: go to Websites & Domains → SSL/TLS Certificates and check if renewal is pending.

The cleanest approach on shared hosting is to let the control panel manage the certificates and avoid installing certbot separately.

For broader context on SSL certificate management, explore our SSL security article hub.

Force a Manual Renewal When Urgent

If the certificate has already expired (or is about to) and you need to renew it right now:

certbot renew --force-renewal

Or for a specific domain:

certbot certonly --force-renewal -d yourdomain.com -d www.yourdomain.com

After renewal, reload Apache or nginx to load the new certificate files:

systemctl reload apache2
# or
systemctl reload nginx

Quick Diagnosis Table

Log symptom Likely cause Fix
Connection refused Port 80 closed Open port 80 in firewall
404 on /.well-known/ Path redirected or blocked Exclude the path from redirect
DNS NXDOMAIN Domain doesn't resolve Check DNS / wait for propagation
certbot.timer inactive Timer is off systemctl enable --now certbot.timer
No error but no renewal Certbot outdated snap refresh certbot

Key Takeaways

  • Let's Encrypt stops auto-renewing when the systemd timer/cron is inactive or when HTTP-01 validation fails.
  • Use certbot renew --dry-run to reproduce the exact error without touching real certificates.
  • Port 80 must be open for HTTP-01 validation even if your site only serves HTTPS traffic.
  • Exclude /.well-known/acme-challenge/ from any HTTP→HTTPS redirect in .htaccess.
  • On shared hosting, let AutoSSL (cPanel) or your panel's built-in tool handle certificates.
  • After a manual renewal, always reload Apache or nginx to activate the new certificate.

Want to hand off SSL management entirely and never worry about renewals again? Our team at elenlace.com handles the full setup and keeps your certificates current year-round.

FAQ

How far in advance does certbot try to renew?

Certbot attempts renewal when fewer than 30 days of validity remain. Since Let's Encrypt issues 90-day certificates, the renewal window opens around day 60. If the first attempt fails, certbot will retry on the next cron cycle — typically 12 hours later.

Will I get a warning before the certificate expires?

Yes. Let's Encrypt sends email alerts to the address registered when the certificate was first issued: a notification 20 days before expiry and another at 7 days. If you're not receiving them, verify the registered email with certbot show_account and check your spam folder.

Can I use Let's Encrypt on hosting without SSH access?

Yes, but it depends on the control panel. cPanel with AutoSSL and Plesk with its native integration both manage Let's Encrypt without SSH. DirectAdmin also has native integration. If your panel doesn't support it, you'll need SSH access or the ability to use the DNS-01 validation method through your DNS provider's API.

Why does Let's Encrypt fail even though the domain loads fine in my browser?

Let's Encrypt's validation servers access your domain from their own infrastructure on the internet, not from your local network. Your domain may work fine from your browser (using local DNS or cached results) while Let's Encrypt's servers see a different IP, a firewall, or a redirect that blocks the challenge. Always test with curl -I http://yourdomain.com/.well-known/acme-challenge/test from an external server to simulate what Let's Encrypt sees.

Prefer it done for you? El Enlace handles hosting and professional web development.

Useful resources

Other providers and guides worth comparing:

← All