How to fix Let's Encrypt certificate renewal problems

Let's Encrypt certificates last about 90 days, and Certbot is meant to renew them quietly in the background. When it silently stops, you find out when visitors see a browser warning that your site's certificate has expired. This guide shows how to check that renewal is set up, how to test it safely and how to fix the usual causes.

Check what you have

List the certificates Certbot manages and their expiry dates:

sudo certbot certificates

Each entry shows the domains, the expiry date and how many days are left. Renewal normally happens when fewer than 30 days remain, so anything under that without a fresh date means renewal is failing.

Is automatic renewal actually scheduled?

Certbot installs either a systemd timer or a cron job. Check for the timer:

systemctl list-timers | grep certbot

If nothing is listed, look for a cron entry in /etc/cron.d/certbot. If neither exists, nothing is renewing your certificate. A timer or cron job is how it is meant to run. For background on scheduled jobs, see How to schedule tasks with cron.

Test renewal safely

Do not wait for expiry to find a problem. Run a dry run, which contacts the staging server and changes nothing real:

sudo certbot renew --dry-run

If it ends with "all simulated renewals succeeded", you are fine. If not, the output names the domain and the reason. Common errors follow.

Common failures

Port 80 is blocked or used

The default HTTP challenge needs the Let's Encrypt servers to reach your server on port 80. Check that:

DNS no longer points at this server

If a domain now points elsewhere, validation fails. Check with dig yourdomain.com A +short and compare with your server's address. See DNS records explained. If you moved a site, remove the old domain from the certificate rather than leaving it to fail.

The web server config changed

Certbot's nginx and Apache plugins edit your configuration. If you restructured the config, renewal may not find the right server block. Test with sudo nginx -t, and make sure each domain has a matching server_name.

A redirect breaks the challenge

The challenge is requested at /.well-known/acme-challenge/. A rule that redirects everything to HTTPS is fine, but one that redirects to a different host, or a proxy that returns a login page, breaks it. Test it yourself:

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

You should get a 404 from your own server, not a redirect elsewhere or a block page.

Proxies such as Cloudflare

If a proxy sits in front, validation may see the proxy rather than your server. Either allow the challenge through, use the DNS challenge, or use the proxy's own certificate and a Cloudflare origin certificate on the server.

Rate limits

Let's Encrypt limits how many failed validations and duplicate certificates you can request. If you hammered the live server while debugging, wait, and use --dry-run or the staging environment while testing.

The server cannot reach out

Certbot must contact Let's Encrypt over HTTPS. DNS resolution problems, a full disk or a broken clock can stop it. Check df -h and timedatectl. See Fixing "No space left on device".

Force a real renewal

Once you have fixed the cause:

sudo certbot renew
sudo systemctl reload nginx

Reload your web server afterwards so it picks up the new certificate files. You can automate that with a deploy hook:

sudo certbot renew --deploy-hook "systemctl reload nginx"

Put the hook in /etc/letsencrypt/renewal-hooks/deploy/ so it runs every time.

Read the logs

Certbot logs details here:

sudo less /var/log/letsencrypt/letsencrypt.log

Search for the word "error" or the domain name. How to read your server logs has tips for long files.

Wildcard certificates

A certificate for *.example.com requires the DNS challenge, because the server cannot be proven by a web file. Renewal then needs a DNS plugin and API access to your DNS provider, which is a frequent source of silent failure when an API token expires or is revoked.

Prevention checklist

  1. Run certbot renew --dry-run after any change to the web server, firewall or DNS.
  2. Keep ports 80 and 443 open.
  3. Monitor expiry from outside, with a free uptime service that warns before a certificate expires.
  4. Remove domains you no longer use.
  5. Keep a note of how each certificate was issued.

For first-time setup, start with How to set up an SSL certificate.


Still stuck? Open a ticket on Discord - run /ticket in any channel, pick a department, and include your Server ID or Invoice ID so we can jump straight in.