Let's Encrypt Renewal Failed: Troubleshooting Guide
Let's Encrypt certificates expire every 90 days. Certbot handles renewal automatically — until it doesn't. When renewal fails silently, you discover it when your site shows a certificate error to all visitors. Here's how to diagnose and fix every common failure scenario.
Run Renewal Manually First
Always start by running renewal manually to see the actual error:
# Run as root / sudo sudo certbot renew --dry-run
The --dry-run flag tests without actually renewing. Remove it for real renewal. Certbot's error output will tell you exactly what failed.
# Check renewal logs sudo cat /var/log/letsencrypt/letsencrypt.log | tail -100
Error: Connection Refused / Port 80 Blocked
Error: Challenge failed for domain example.com Connection refused
The HTTP-01 challenge requires port 80 to be accessible from the internet. Check:
# Check if port 80 is listening sudo ss -tlnp | grep :80 # Check firewall sudo ufw status sudo ufw allow 80/tcp
If you're using Cloudflare or a load balancer that strips port 80, switch to DNS-01 challenge (see below).
Error: ACME Challenge File Not Found
Error: 404 Not Found /.well-known/acme-challenge/xxxxx
The challenge file is created but your web server is not serving it. Common causes:
Ensure --webroot-path matches your actual web root (e.g., /var/www/html)
Add an exception before catch-all rewrites: location ^~ /.well-known/acme-challenge/ { root /var/www/html; }
Ensure /.well-known/ is excluded from application routing
Error: Rate Limit Exceeded
Error: too many certificates already issued
Let's Encrypt rate limits: 50 certificates per registered domain per week, 5 duplicate certificates per week. If you hit limits: wait until the limit resets, use the staging environment for testing (--staging flag), and avoid re-issuing when renewals will suffice.
Switch to DNS-01 Challenge
DNS-01 works even when port 80 is blocked, behind Cloudflare, or for wildcard certificates:
# Install Cloudflare DNS plugin (example) sudo pip install certbot-dns-cloudflare # Create credentials file sudo mkdir -p /etc/letsencrypt/cloudflare echo "dns_cloudflare_api_token = YOUR_TOKEN" | sudo tee /etc/letsencrypt/cloudflare/credentials.ini sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini # Issue wildcard certificate sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini -d "*.yourdomain.com" -d "yourdomain.com"
Verify Auto-Renewal is Set Up
# Check if systemd timer is active (modern systems) sudo systemctl status certbot.timer # Or check cron sudo crontab -l | grep certbot # Manual cron entry if missing 0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
Renewal Checklist
Use our free SSL Certificate Checker to immediately verify whether your current certificate is valid and how many days remain before expiry.
Common questions
Why does Let's Encrypt renewal fail silently?
Certbot logs failures to /var/log/letsencrypt/letsencrypt.log but does not alert unless configured. The cron job runs, fails, and the log entry is the only evidence. To catch failures proactively: configure Certbot's --deploy-hook to send a success notification, and monitor certificate expiry independently with a service that alerts you before the certificate actually expires.
What are the most common Let's Encrypt renewal failure causes?
Port 80 blocked by firewall (required for HTTP-01 challenge), web server down when renewal runs, domain A record pointing to a different server than where Certbot runs, rate limits reached from too many failed attempts, and outdated Certbot unable to communicate with Let's Encrypt's ACME v2 API. Check /var/log/letsencrypt/letsencrypt.log for the specific error.
How do I manually renew a Let's Encrypt certificate?
Run certbot renew --force-renewal to renew all certificates regardless of expiry. For a specific domain: certbot certonly --force-renewal -d yourdomain.com. Always test with --dry-run first: certbot renew --dry-run. After renewal, reload your web server: systemctl reload nginx or systemctl reload apache2. Verify the new certificate is live using an SSL checker.
What is the Let's Encrypt rate limit for failed validations?
Let's Encrypt limits failed validation attempts to 5 per hour per domain. If you repeatedly attempt renewal and fail (e.g. port 80 blocked), you'll be rate-limited and subsequent attempts also fail. Fix the underlying issue before retrying. Use the --staging flag while debugging to avoid hitting production rate limits.
References and further reading
The specifications and primary documentation this article is based on.
Read next
More guides on the same subject.