---
title: "Let's Encrypt Auto-Renewal Failures: ACME Failure Modes Explained | FourSight"
description: "HTTP-01 blocked by a firewall, DNS-01 broken by a nameserver migration, rate limits, dead certbot timers — the real ways ACME renewal breaks and how to detect each."
lang: en
json-ld: |
  [
    {
      "@context": "https://schema.org",
      "@type": "Article",
      "headline": "Let's Encrypt Auto-Renewal Failures: ACME Failure Modes Explained",
      "description": "HTTP-01 blocked by a firewall, DNS-01 broken by a nameserver migration, rate limits, dead certbot timers — the real ways ACME renewal breaks and how to detect each.",
      "author": {
        "@type": "Organization",
        "name": "FourSight"
      },
      "publisher": {
        "@type": "Organization",
        "name": "FourSight"
      },
      "url": "https://foursight.cloud/guides/lets-encrypt-renewal-failures",
      "mainEntityOfPage": "https://foursight.cloud/guides/lets-encrypt-renewal-failures",
      "datePublished": "2026-07-14",
      "dateModified": "2026-07-14",
      "wordCount": 1800
    },
    {
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://foursight.cloud"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Guides",
          "item": "https://foursight.cloud/guides"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Let's Encrypt Auto-Renewal Failures: ACME Failure Modes Explained",
          "item": "https://foursight.cloud/guides/lets-encrypt-renewal-failures"
        }
      ]
    },
    {
      "@context": "https://schema.org",
      "@type": "FAQPage",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "How often does certbot try to renew certificates?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "By default certbot's systemd timer (or cron entry) runs twice a day, and each run renews any certificate within 30 days of its expiry. A healthy 90-day Let's Encrypt certificate is therefore replaced around day 60 — which means about 60 scheduled attempts stand between a first silent failure and an actual expiry, if the failure mode is consistent."
          }
        },
        {
          "@type": "Question",
          "name": "Does Let's Encrypt email me before my certificate expires?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "No — not anymore. Let's Encrypt ended its expiration notification emails in 2025, explicitly recommending external monitoring instead. If your renewal safety net was 'we'll get an email,' it no longer exists."
          }
        },
        {
          "@type": "Question",
          "name": "Why do wildcard renewals fail more often than single-domain ones?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Wildcards require the DNS-01 challenge, which depends on an API credential for your DNS provider staying valid indefinitely. Token rotations, provider migrations, and permission changes all silently break it. Single-domain HTTP-01 renewals have failure modes too, but they don't carry the standing credential dependency."
          }
        },
        {
          "@type": "Question",
          "name": "What is the Let's Encrypt staging environment for?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "It's a parallel ACME endpoint with much higher rate limits that issues certificates signed by a non-trusted test CA. Use it (certbot's --dry-run uses it automatically) to validate your challenge path, DNS plugin, and deploy hooks without spending production rate-limit quota — especially before and after infrastructure changes."
          }
        },
        {
          "@type": "Question",
          "name": "My renewal succeeded but the site still serves the old certificate. Why?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "The web server or load balancer loaded the certificate into memory at startup and was never told to reload it. Add a deploy hook (for example, certbot's --deploy-hook 'systemctl reload nginx'), and verify externally: check what certificate the live endpoint actually serves, not what's on disk."
          }
        },
        {
          "@type": "Question",
          "name": "Can FourSight tell me why my renewal failed?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "It tells you that renewal has failed — the served certificate is aging past its expected replacement point — with the certificate evidence (issuer, SANs, expiry) attached, from 30 days out. Diagnosing which failure mode applies is then a short checklist: is the timer running, does --dry-run pass, and does the served cert match the renewed file."
          }
        }
      ]
    }
  ]
---

[FourSight ](/)

[Features](/#features)[Pricing](/pricing)[Guides](/guides)[Glossary](/glossary)[FAQ](/faq)

[Login](/auth)[Start free](/auth?signup=true)

[Start free](/auth?signup=true)

[All Guides](/guides)

Reliability & Infrastructure

# Let's Encrypt Auto-Renewal Failures: ACME Failure Modes Explained

HTTP-01 blocked by a firewall, DNS-01 broken by a nameserver migration, rate limits, dead certbot timers — the real ways ACME renewal breaks and how to detect each.

9 min read Guide Published Jul 14, 2026 

## The Short Version

[Let's Encrypt](/glossary/lets-encrypt "Glossary: Let's Encrypt") renewals fail in a handful of predictable ways: the ACME client stops running, the validation challenge can't reach you (blocked port 80, broken redirect, misbehaving [CDN](/glossary/cdn "Glossary: CDN")), the [DNS](/glossary/dns "Glossary: DNS") API credential behind a DNS-01 challenge silently rotates, you hit a rate limit, or the renewal succeeds but the web server never reloads. Every one of these failure modes shares a nasty property — the system believes things are fine, or says nothing at all, until the certificate expires weeks later. This guide walks through each mode with the specific error signatures and fixes, because 'auto-renewal' is doing a lot of load-bearing work in most teams' security posture. Let's Encrypt issues 90-day certificates precisely on the assumption that renewal is automated and verified; the verification half is on you.

Related Reading

-   [→ Feature: SSL certificate monitoring](/features/ssl-monitoring)

## How ACME Renewal Actually Works

ACME — the Automatic Certificate Management Environment, standardized in RFC 8555 — is the protocol behind Let's Encrypt and an increasing number of other CAs. Renewal is really re-issuance: the client (certbot, acme.sh, Caddy's built-in client, lego, cert-manager) creates a new order, the CA issues a challenge proving you control the domain, the client satisfies the challenge, and the CA signs a fresh certificate. Certbot's defaults illustrate the intended rhythm: a systemd timer fires twice daily, and each run renews any certificate within 30 days of expiry. That means a healthy 90-day certificate gets replaced around day 60 — and it means roughly 30 days of scheduled renewal attempts stand between the first silent failure and an actual outage. That 30-day buffer is your entire safety margin; monitoring exists to tell you when you've started spending it.

### The Three Challenge Types

HTTP-01: the CA fetches a token from http://yourdomain/.well-known/acme-challenge/<token> over port 80. DNS-01: the client publishes a [TXT record](/glossary/txt-record "Glossary: TXT record") at \_acme-challenge.yourdomain and the CA queries for it — required for wildcard certificates. [TLS](/glossary/ssl-tls "Glossary: TLS")\-ALPN-01: validation happens inside a TLS handshake on port 443 using the acme-tls/1 ALPN protocol, useful when port 80 is impossible. Each challenge type fails differently, which is why diagnosing a renewal failure starts with knowing which one you use.

## HTTP-01 Failure Modes

HTTP-01 is the most common challenge and fails for reasons that are almost always environmental rather than cryptographic. The CA must be able to make a plain HTTP request to your domain on port 80 and get the token back — anything that intercepts, blocks, or rewrites that request breaks issuance.

### Port 80 Blocked or Firewalled

A security review closes port 80 ('we're HTTPS-only'), and renewals start failing on the next cycle. HTTP-01 validation requires port 80 to be reachable; redirects from 80 to 443 are fine and followed, but a connection-refused or filtered port is fatal. This failure is especially common after infrastructure moves where the new security group defaults were stricter than the old ones.

### Redirect and Routing Mishaps

Aggressive redirect rules that send /.well-known/acme-challenge/ requests to a www subdomain, an app router that treats the path as a 404-able application route, or an auth middleware that demands a login for every path — all return the wrong thing to the validation server. The fix is an explicit carve-out: serve the challenge path before any rewriting, authentication, or framework routing gets a chance to touch it.

### A CDN or Proxy in the Middle

Put Cloudflare or another proxy in front of an origin whose certbot expects to answer challenges directly, and validation requests may be cached, challenged with a bot check, or terminated at the edge without reaching the origin. Teams typically hit this the first renewal cycle after enabling a proxy — issuance worked at setup time, then quietly broke.

### The IPv6 Trap

If your domain has an [AAAA record](/glossary/aaaa-record "Glossary: AAAA record"), Let's Encrypt prefers validating over IPv6. A stale or wrong AAAA record — pointing at an old server, or at a host where the web server isn't bound to the v6 address — fails validation even though every IPv4 user finds your site perfectly. This one generates genuinely baffled debugging sessions because 'the site is up' and the renewal logs disagree.

### Monitoring a Commercial SaaS?

FourSight's free plan includes 10 commercial-safe monitors with multi-region validation — free forever, no card.

[Start Monitoring Free](/auth?signup=true)

## DNS-01 Failure Modes

DNS-01 challenges trade the port-80 dependency for a DNS-provider API dependency, and that API credential becomes a load-bearing secret most teams forget exists. Wildcard certificates require DNS-01, so wildcard estates inherit all of these modes.

### Rotated or Expired API Tokens

The renewal plugin authenticates to your DNS provider to publish the \_acme-challenge TXT record. A routine token rotation, a security policy that expires stale credentials, or an account ownership change breaks that authentication. The renewal fails cleanly in the logs — 'unauthorized' — but nothing escalates the log line to a human. This is the single most common wildcard-renewal killer.

### Nameserver Migrations

Move DNS from one provider to another and the renewal configuration still points its API calls at the old provider. The TXT record gets published — into a zone no resolver consults anymore. Validation times out. Renewal configuration is almost never on anyone's DNS-migration checklist, which is exactly why it should be.

### CAA Records and Propagation Timing

A CAA record that doesn't authorize your CA (easy to introduce when centralizing DNS security settings) blocks issuance outright. Separately, slow propagation between publishing the TXT record and the CA's query can fail validation intermittently — maddening because retries sometimes succeed, so the failure looks flaky rather than structural. Set explicit propagation wait times in your client's DNS plugin configuration.

## Rate Limits: The Failure You Cause Yourself

Let's Encrypt enforces rate limits to protect its free service, and renewal loops gone wrong can trip them. The published limits (as of mid-2026 — check letsencrypt.org for current values) include on the order of 50 certificates per registered domain per week and a small number of duplicate certificates for the same exact name set per week, plus limits on repeated failed validations per hour. The classic self-inflicted incident: a broken deploy pipeline re-issues instead of reusing certificates on every deploy, burns the duplicate-certificate limit, and then a legitimately needed renewal gets refused during the outage you're trying to fix. Two defenses: persist issued certificates properly so re-issuance is rare, and test everything against Let's Encrypt's staging environment, which has far higher limits and exists precisely so your experiments don't spend production quota.

## The Client Itself: When Nothing Runs at All

The most silent failure of all is the ACME client that never executes. A certbot systemd timer disabled during a distribution upgrade; a cron entry that lived in a crontab wiped by a server rebuild; a container image that includes certbot but no scheduler to invoke it; a Kubernetes cert-manager deployment whose ServiceAccount lost permissions. And the near-miss variant: the client runs, renews successfully, and writes the new certificate — but the missing --deploy-hook means nginx never reloads, so the live endpoint serves the old certificate until it expires anyway. Verify both halves explicitly: 'systemctl list-timers | grep certbot' proves the schedule exists, and an external check of the served certificate proves renewals actually reach the internet.

```
# Is the renewal timer actually scheduled?
systemctl list-timers | grep -i certbot

# Dry-run the full renewal path against staging (safe, no quota)
certbot renew --dry-run

# What certificate is ACTUALLY being served right now?
echo | openssl s_client -servername yourdomain.com \
    -connect yourdomain.com:443 2>/dev/null \
  | openssl x509 -noout -subject -issuer -enddate

# Renewal with a deploy hook so the new cert actually goes live
certbot renew --deploy-hook "systemctl reload nginx"
```

## Detecting Renewal Failures Before They Become Outages

Every failure mode above eventually produces the same observable symptom: the certificate served on port 443 keeps aging past the point where renewal should have replaced it. That makes external monitoring the universal detector. A daily-or-better check that performs a real TLS handshake and reads the served certificate's expiry catches a broken renewal roughly 30 days before impact — for a 90-day Let's Encrypt certificate renewed at day 60, an alert threshold at 25-30 days remaining fires almost immediately after the first missed renewal window. FourSight's SSL monitor does exactly this from four regions, alerting at 30, 14, and 7 days by default (configurable), with chain and hostname validation on every check. You can also add a [heartbeat monitor](/glossary/heartbeat-monitor "Glossary: heartbeat monitor") to the renewal job itself — have the cron ping after each successful run — to distinguish 'renewal never ran' from 'renewal ran and failed,' which shortcuts the first diagnostic step at 2 AM.

[Set up SSL expiry monitoring →](/features/ssl-monitoring)

Related Reading

-   [→ How SSL certificates expire silently: the failure modes](/guides/how-ssl-certificates-expire-silently)
-   [→ Wildcard vs SAN certificates: monitoring implications](/guides/wildcard-vs-san-certificate-monitoring)
-   [→ Heartbeat monitoring for cron jobs & scheduled tasks](/guides/heartbeat-monitoring-cron-jobs)

## Frequently Asked Questions

### How often does certbot try to renew certificates?

### Does Let's Encrypt email me before my certificate expires?

### Why do wildcard renewals fail more often than single-domain ones?

### What is the Let's Encrypt staging environment for?

### My renewal succeeded but the site still serves the old certificate. Why?

### Can FourSight tell me why my renewal failed?

#### Related Guides

[What Is Uptime Monitoring? The Complete Guide 12 min ](/guides/what-is-uptime-monitoring)[Multi-Region Monitoring Explained 8 min ](/guides/multi-region-monitoring-explained)[SSL Certificate Expiry Monitoring 10 min ](/guides/ssl-certificate-expiry-monitoring)[How SSL Certificates Expire Silently: The Failure Modes 8 min ](/guides/how-ssl-certificates-expire-silently)

#### Compare FourSight

[vs UptimeRobot →](/compare/uptimerobot-alternative)[vs StatusCake →](/compare/statuscake-alternative)[vs Pingdom →](/compare/pingdom-alternative)

10 free commercial-safe monitors

[View Pricing](/pricing)

## Protect Your SaaS Revenue

Start monitoring in under 60 seconds.

[Start Monitoring Free](/auth?signup=true)[View Pricing](/pricing)

FourSight 

© 2026 [TetraCore](https://tetracorehq.com/). All rights reserved.

FourSight is a TetraCore product — Bowling Green, Ohio.

Product

[Pricing](/pricing)[Guides](/guides)[Glossary](/glossary)[FAQ](/faq)[About](/about)[For Agencies](/solutions/agencies)[For Startups](/solutions/startups)[Privacy](/privacy)[Terms](/terms)

Features

[Cron Job & Heartbeat Monitoring](/features/cron-job-monitoring)[SSL Certificate Monitoring](/features/ssl-monitoring)[Status Pages](/features/status-pages)[Domain Expiry Monitoring](/features/domain-expiry-monitoring)[DNS Monitoring](/features/dns-monitoring)[Port Monitoring](/features/port-monitoring)

Compare

[All comparisons](/compare)[vs UptimeRobot](/compare/uptimerobot-alternative)[vs StatusCake](/compare/statuscake-alternative)[vs Freshping](/compare/freshping-alternative)[vs Pingdom](/compare/pingdom-alternative)[vs Pulsetic](/compare/pulsetic-alternative)[vs Better Stack](/compare/better-stack-alternative)[vs Uptime Kuma](/compare/uptime-kuma-alternative)[vs Cronitor](/compare/cronitor-alternative)[vs Healthchecks.io](/compare/healthchecks-alternative)[vs Hyperping](/compare/hyperping-alternative)

Pricing Guides

[UptimeRobot Pricing](/compare/uptimerobot-pricing)[StatusCake Pricing](/compare/statuscake-pricing)[Pingdom Pricing](/compare/pingdom-pricing)[Better Stack Pricing](/compare/better-stack-pricing)[Uptime Kuma Pricing](/compare/uptime-kuma-pricing)[Cronitor Pricing](/compare/cronitor-pricing)[Healthchecks.io Pricing](/compare/healthchecks-pricing)[Hyperping Pricing](/compare/hyperping-pricing)[Pulsetic Pricing](/compare/pulsetic-pricing)