SSL Auto Renewal Failed – Let's Fix It Now

Server & Cloud Intermediate 👁 9 views 📅 Jun 24, 2026

SSL cert renewal fails because the validation check can't reach your server. Here's the real fix and why it works.

Yeah, SSL auto renewal failed. It happens. The email says validation failed and you're staring at a soon-expiring cert. Let's skip the panic and fix it.

The Immediate Fix

First, check if the renewal process can actually reach your server. This is the most common reason it fails. Run this command as root or with sudo:

certbot renew --dry-run

If that fails, you'll see an error like "Failed to connect to ... port 80" or "urn:ietf:params:acme:error:connection". The fix is to make sure port 80 (HTTP) and port 443 (HTTPS) are open from the internet. Most Let's Encrypt clients use HTTP-01 challenge by default, which means they need to connect to your server on port 80 and fetch a specific file from /.well-known/acme-challenge/ directory.

Here's what you do:

  1. Log into your server via SSH.
  2. Check your firewall: sudo ufw status or sudo iptables -L -n. Make sure port 80 and 443 are allowed.
  3. If you're behind a router, check port forwarding. Your router must forward port 80 and 443 to the internal IP of your server.
  4. Restart your web server: sudo systemctl restart nginx or sudo systemctl restart apache2.
  5. Try the dry run again.

If the dry run passes, your auto renewal will work next time. The real problem was that the cert validation server couldn't reach your machine.

Why This Fix Works

Let's Encrypt uses ACME protocol. When you request a cert renewal, the client (certbot) tells Let's Encrypt to verify you own the domain. For HTTP-01 challenge, Let's Encrypt checks if a special file exists at http://yourdomain.com/.well-known/acme-challenge/<token>. If port 80 is blocked, this check times out. The fix opens that port so the validation can happen.

What's actually happening here is that the renewal cron job runs but the network path isn't ready. The cron job doesn't fail because of a bug – it fails because the server isn't reachable. So opening port 80 is the real fix in 90% of cases.

Less Common Variations

DNS-01 Challenge

If you're using wildcard certs, you probably use DNS-01 challenge. That one checks a TXT record in your DNS zone. The fix there is different: you need your DNS provider's API credentials set up correctly in certbot. The error usually says "No TXT record found" or "DNS query failed." Check your DNS provider's docs for API key setup. For Cloudflare, you need a Global API Key or API token with DNS edit permission. For Namecheap, get your API key from your account settings.

TLS-ALPN-01 Challenge

This one requires port 443 and a specific ALPN protocol. It's rare but happens with some setups like HAProxy or custom backends. The error looks like "TLS ALPN negotiation failed." Fix: make sure your server supports TLS-ALPN-01. Most web servers do by default. If not, switch to HTTP-01 in your certbot config.

Renewal Timeout

Sometimes the renewal process just hangs and times out. This happens when the server is slow or overloaded. The fix: check your server load with top or htop. If it's at 100%, wait or upgrade. Also check the cron job runs at a sane time – not during peak hours. Set it to run at 3 AM.

Prevention – Stop It From Happening Again

You don't want this email next month. Here's what I do:

  • Set up a monitoring check that tests port 80 and 443 from outside. Use a free service like UptimeRobot or a simple curl from another server.
  • Add a cron job that runs certbot renew --quiet twice a day. Let's Encrypt certs last 90 days, so twice a day catches it early.
  • Keep your web server logs for the renewal directory. Check /var/log/nginx/access.log for requests to /.well-known/. If you see none during renewal, something's blocking.
  • Also, make sure your system clock is accurate. SSL validation uses time. Run sudo timedatectl set-ntp true to sync with NTP.

That's it. Your auto renewal won't fail again unless you change firewall or DNS settings. And if it does, you now know where to look.

Was this solution helpful?