Docket

TROUBLESHOOTING

Let's Encrypt will not issue your certificate

Before you retry again, read the rate limits. Five issuances of the same name in a week is the wall, and it refills at one every 34 hours.

7 MIN READ Last updated 23 August 2026

Stop retrying. Every failed run costs you quota, and the wall is closer than people expect: five certificates for the same set of names in any seven days, refilling at one every 34 hours. Switch your client to the staging environment, fix the challenge there where the limits are enormous, then go back to production once and get the certificate.

That instruction is worth more than the rest of this page. The rest is how to find which cause you have.

What are the rate limits, exactly?

These are the current values from Let's Encrypt's own rate-limit page, whose header reads last updated 5 August 2026. They are enforced with a token bucket, so each has a refill rate rather than a clean weekly reset.

LimitValueRefill rate
New orders per account300 every 3 hours1 every 36 seconds
Certificates per registered domain50 every 7 days1 every 202 minutes
Certificates per exact set of identifiers5 every 7 days1 every 34 hours
Authorisation failures per identifier per account5 an hour1 every 12 minutes

The third row is the one that bites, because reinstalling a client or wiping its configuration while you debug produces a fresh order for exactly the same hostname each time. Let's Encrypt says it set that one deliberately low to stop software under development consuming the capacity of the other limits. The fourth row is gentler than it sounds: a run of failed validations locks that hostname for the hour, not the week.

There is no appeal and no reset button.

If you've hit a rate limit, we don't have a way to temporarily reset it.

Let's Encrypt, Rate Limits

Revoking the certificates you did manage to get does not help either, because the capacity was already spent issuing them.

How do you debug without spending quota?

Point your client at the staging environment first. It behaves identically, issues certificates from untrusted roots with names like "(STAGING) Pretend Pear X1", and raises the exact-set limit from 5 a week to 30,000 and the authorisation-failure limit from 5 an hour to 200.

With Certbot, one flag does it:

certbot certonly --dry-run -d support.example.com

For anything else, the directory URL is the switch:

https://acme-staging-v02.api.letsencrypt.org/directory

Caddy takes it as a global acme_ca option, Traefik as caServer on the certificate resolver, and Nginx Proxy Manager has a staging toggle in the dialogue where you request the certificate. Accounts are scoped per environment, so your client registers a fresh one automatically.

Do the whole debugging loop there. Only when a staging run succeeds should you remove the flag.

Why is the challenge failing?

The certificate is not the thing that failed. The challenge is. Let's Encrypt has to prove you control the name, and for the HTTP challenge it does that by fetching a file from your server over plain HTTP on port 80. Its own documentation is direct about where that goes wrong: failures "usually stem from network or firewall configurations that prevent Let's Encrypt validation servers from reaching your server."

The shape of it in a certbot log, as pasted in an open Nginx Proxy Manager issue that has run to 81 comments since November 2023, with the reporter's own host swapped for a placeholder:

Domain: support.example.com
Type:   connection
Detail: Fetching
  http://support.example.com/.well-known/acme-challenge/MS4A5...:
  Connection reset by peer

The same log ends with certbot's own hint, that the authority "failed to download the temporary challenge files" and that the listed domains must serve them from the configured webroot in a way that can be downloaded from the internet.

Connection reset by peer means something answered and hung up. Nothing at all on port 80 gives you a timeout instead. Either way, reproduce it yourself from outside your own network:

curl -sS -o /dev/null -w "%{http_code}\n" \
  http://support.example.com/.well-known/acme-challenge/test

A 404 is the good answer: the request reached your web server and it answered. Anything else, a timeout, a connection reset, or a redirect to HTTPS that then fails, is your actual bug. Check what is listening:

sudo ss -lntp | grep ':80'

And check that the name resolves to the machine you think it does, on both address families, because a stale AAAA record pointing at nothing is a classic silent failure:

dig +short A    support.example.com @1.1.1.1
dig +short AAAA support.example.com @1.1.1.1

The fix, in order

1. Run the curl above from a machine outside your network. If it does not return a status code, no ACME client will ever succeed, and nothing you change in the client matters.

2. Open port 80 inbound on the host firewall and, on a cloud VPS, in the provider's own security group as well. Both exist and people routinely fix one and forget the other.

3. Remove or fix any AAAA record whose address does not answer.

4. If Cloudflare is proxying the name, either set the record to DNS only for the duration of issuance, or stop using the HTTP challenge and switch to the DNS challenge instead, which never needs an inbound port.

5. Check CAA records on the registered domain. If one exists and does not name your authority, issuance is refused before the challenge is even attempted.

dig +short CAA example.com @1.1.1.1

6. Re-run against staging until it succeeds, then remove the staging flag and run once against production.

Your own support centre, in your own repository

One payment, no subscription, unlimited products.

How do you know it worked?

Look at the certificate the server is actually serving, not at what the client logged:

openssl s_client -connect support.example.com:443 \
  -servername support.example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

If the issuer still says STAGING, you left the flag on and the certificate will not be trusted by any browser. If the dates are old, your server is serving a cached or previous certificate and needs a reload.

You can also confirm from outside, without touching the server. Let's Encrypt points people at crt.sh and Censys, which read the public Certificate Transparency logs, so searching your domain shows every certificate issued for it and by whom. That is also how to count the weekly quota you have already spent.

Same failure, different cause

What you seeCauseFix
Connection reset by peer on the challenge URLPort 80 blocked, or a proxy answering and closingOpen port 80 inbound, on the host and at the provider
Timeout fetching the challengeNothing listening, or DNS points elsewhereCheck ss -lntp and the A and AAAA records
could not get certificate from issuer from CaddyDNS challenge credentials or zone wrongCheck the API token's zone scope, as in the Caddy thread on this exact message
Refused before any challenge runsCAA record excludes the authorityAdd the authority to the CAA record set
too many certificates already issuedExact-set limit spent on retriesWait for refill at one every 34 hours, and debug on staging
Works, browser still warnsStaging certificate in placeRemove the staging flag and reissue

What if you are not running a server at all?

Then most of this stops applying, and that is worth saying plainly rather than at the end of a sales pitch. A support centre built as static files has no ACME client, no port 80 to open and no renewal cron, because the certificate is issued and renewed by whichever host serves the files. That is how Docket works: it is a static site in your own repository, so certificate management belongs to Netlify, Vercel, Cloudflare Pages or whoever you deploy to, and the only failure mode left is the DNS one covered in your custom domain is stuck on Verifying.

If you are running your own box on purpose, what breaks when you self-host is the honest list of what you take on, and certificate renewal is on it.

Frequently asked questions

How long am I locked out after hitting the duplicate-certificate limit?

Capacity comes back one certificate every 34 hours, so a fully spent bucket takes about a week to refill completely, and you can issue again as soon as the first slot returns. There is no way to shorten it and revoking certificates does not help.

Does a failed attempt count against the certificate limit?

No. Failed validations count against the authorisation-failure limit, which is 5 an hour per hostname and refills every 12 minutes. Successful issuances count against the certificate limits. The reason people hit the weekly wall while debugging is that some of their attempts do succeed and are then thrown away.

Can I avoid the whole problem by using the DNS challenge?

Often, yes. The DNS challenge proves control by publishing a TXT record rather than serving a file, so it needs no inbound port and works on a machine with no public web server. The tradeoff is that your ACME client needs API credentials for your DNS provider, scoped to that one zone.

Do renewals count against my rate limits?

Renewals coordinated by ACME Renewal Info, which most current clients support, are exempt from all rate limits. Older renewal detection, which just recognises an order for the same set of names, is still subject to some of them. Keeping your client up to date is the practical answer.

Why does the certificate work in a browser but fail from a script?

Usually because the server is not sending the intermediate certificate, which browsers often paper over from cache and command-line tools do not. The openssl s_client output above shows the full chain the server actually sends, which is where to check.