DNS challenge (ACME DNS-01)

DNS-01 proves domain control by publishing a TXT record. The only ACME challenge that works for wildcard certs and on hosts not reachable on port 80.

The ACME DNS-01 challenge proves you control a domain by publishing a TXT record at _acme-challenge.<domain> containing a digest the certificate authority can recompute. It is the only ACME challenge that can issue wildcard certificates, and the only one that works before the host is reachable on port 80.

That last property is why every custom-domain platform uses it. You can have a valid certificate waiting before your customer's traffic ever arrives.

The exact record

Per RFC 8555 section 8.4, the value is not the token. It is:

base64url( SHA-256( token "." base64url(Thumbprint(accountKey)) ) )

which comes out as 43 unpadded base64url characters. Two consequences people trip on:

  • The same token gives different TXT values for different ACME accounts. You cannot copy a challenge value between environments.
  • The record is a TXT record, not a CNAME or a URL. _acme-challenge is a label, not a real host, and nothing ever resolves it for traffic.

Check what is published with dig or the TXT record lookup:

dig +short TXT _acme-challenge.example.com

Why wildcards force DNS-01, and the two-record trap

HTTP-01 validates one exact hostname by serving a file on it. There is no file you can serve that proves control over *.example.com, so the CA will not accept it. DNS-01 asks the zone instead, and control of the zone is control of every name under it.

The trap: a certificate covering both example.com and *.example.com produces two separate challenges, both answered at the same name _acme-challenge.example.com. They need two TXT records coexisting at that label. Automation that "sets" the record instead of appending overwrites the first with the second, and the order fails half-validated. If you have ever seen a SAN certificate request stall on exactly one identifier, this is usually why.

CNAME delegation is the part that makes DNS-01 safe

Let's Encrypt is blunt about the downside of DNS-01: "putting your full DNS API credentials on your web server significantly increases the impact if that web server is hacked." A DNS API token that can write your zone can also rewrite your MX records and your A records.

The fix is delegation, and it is officially supported: you may use CNAME or NS records to point _acme-challenge at a zone you control separately.

_acme-challenge.example.com.  IN  CNAME  example-com.acme.validation.net.

The resolver follows the CNAME, the CA reads the TXT at the target, and the credential that writes the actual challenge only ever has access to validation.net. Your production zone holds one static CNAME that never changes again.

This is also the mechanism behind every custom-domain product. When a platform asks your customer to add a _acme-challenge CNAME alongside their CNAME record, it is doing exactly this: taking over challenge answering so it can renew that customer's certificate forever without ever holding a credential to the customer's zone. The customer sets two records once. The platform handles provisioning and renewal after that.

One thing to watch: a delegated _acme-challenge CNAME pointing at a validation zone you have since torn down is a dangling DNS record. If someone else can claim that target, they can answer challenges for your hostname. Delete the CNAME when you stop using the platform, the same discipline that prevents subdomain takeover.

Pin the method with CAA, before you have to

CAA records already let you say which CAs may issue for your domain. RFC 8657 adds two parameters that most zones do not use yet:

  • accounturi restricts issuance to one specific ACME account.
  • validationmethods restricts it to specific challenge types, for example dns-01 only.
example.com.  IN  CAA  0 issue "letsencrypt.org; validationmethods=dns-01; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/12345"

Together they mean a stolen web server cannot mint a certificate over HTTP-01, and an unrelated ACME account cannot issue at all. The CA/Browser Forum voted in May 2026 to make honouring these parameters mandatory for every CA from March 2027, so support is about to stop being best-effort.

For reference, here is what two real zones publish today, read straight out of DNS on 2026-08-19:

ZoneCAA policy
cloudflare.comfive CAs across issue and issuewild, several with cansignhttpexchanges=yes, plus an iodef mailto for violation reports
github.comfour CAs for issue (Let's Encrypt, DigiCert, Sectigo, GlobalSign) but only three for issuewild, so GlobalSign may not issue its wildcards
domainee.devnone

That last row is honest and common. Most zones, ours included, publish no CAA at all, which means any public CA may issue. A single issue record is the cheapest security control in DNS, and neither of the two useful RFC 8657 parameters appears in either of the real-world examples above yet.

Negative caching is why your first poll costs you an hour

The most common DNS-01 failure is not a wrong record. It is an ACME client that queried _acme-challenge before publishing it.

That query returns NXDOMAIN, and under RFC 2308 a resolver may cache that negative answer for the lesser of the SOA record's own TTL and its MINIMUM field. Publishing the TXT a second later does not clear it. The CA's resolver keeps saying "no such record" until the negative entry expires.

Measured against 1.1.1.1 on 2026-08-19:

ZoneDNS hostSOA TTLSOA MINIMUMEffective negative cache
cloudflare.comCloudflare300300300s
shopify.comFoundation DNS300300300s
stripe.comRoute 539003600900s
porkbun.comRoute 5390086400900s
domainee.devCloudflare17861800~1800s
vercel.comVercel DNS3600144003600s
godaddy.comGoDaddy360036003600s
namecheap.comNamecheap360036003600s

Two things fall out of that. Route 53 zones look alarming if you only read MINIMUM (86400, a full day), but RFC 2308's "lesser of" rule caps them at the SOA's 900-second TTL, so the common warning about day-long Route 53 stalls is wrong. GoDaddy and Namecheap genuinely do sit at a full hour.

So the rule is simple: publish first, then poll, and never poll a name you have not written yet. Good clients wait for the record to be visible on the zone's own authoritative nameservers before telling the CA to validate, which sidesteps recursive resolver caching entirely. If you are debugging one that does not, the DNS propagation checker shows you which resolvers are still holding the stale answer.

Your record now has to be visible from several continents

Since 15 March 2025 the CA/Browser Forum Baseline Requirements have required Multi-Perspective Issuance Corroboration: CAs must confirm domain control from multiple network vantage points, not one. Since 15 September 2025 they must refuse to issue when those perspectives disagree.

For DNS-01 this changes the failure mode. A TXT record that is live on one nameserver but not the others, or a GeoDNS setup that answers differently by region, used to be a coin flip and now reliably fails. Validate against the zone globally, not from the box running the ACME client.

The rate limits that actually bind

Let's Encrypt's published limits, current as of August 2026:

LimitValue
Certificates per registered domain50 per 7 days
Duplicate certificates (identical name set)5 per 7 days
New orders per account300 per 3 hours
Failed validations per identifier per account5 per hour
Accounts per IP10 per 3 hours

For a multi-tenant custom domains platform, the 50-per-registered-domain limit almost never bites, because each customer domain is its own registered domain with its own budget. It bites hard the moment you issue per-tenant certificates for subdomains of your domain: tenant1.app.com, tenant2.app.com and so on all draw from one bucket of 50 per week. The five-failed-validations-per-hour limit is the one that turns a misconfigured retry loop into an outage.

Where this sits in a custom-domain flow

The customer points a CNAME at your edge and adds the _acme-challenge delegation. Your platform answers the challenge in its own zone, receives the certificate, and the edge then selects it per connection by SNI. None of that requires access to the customer's DNS zone, which is the whole reason the delegation pattern exists.

Domainee is a custom domains API for SaaS with a native MCP server — 50 domains and 100 GB free. It runs the DNS-01 delegation and renewal loop above for every connected hostname. The Cloudflare SSL for SaaS setup guide walks the build-it-yourself version, and connecting custom domains to your SaaS covers the customer-facing flow.

FAQ

Does DNS-01 work for wildcard certificates? Yes, and it is the only challenge that does. A CA will not accept HTTP-01 for *.example.com because no single hostname can demonstrate control of every name under the zone. DNS-01 queries the zone itself, which does.

What is the difference between DNS-01 and HTTP-01? HTTP-01 serves a token file over port 80 on the exact hostname being validated. DNS-01 publishes a TXT record at _acme-challenge instead, so it works behind firewalls, before the host has any traffic, and for wildcards. The cost is that it needs write access to DNS, which is why delegation matters.

How long does DNS-01 validation take? Publishing is instant; the wait is DNS. Budget the record's TTL, and be aware that a premature lookup can pin a negative answer for the lesser of the zone's SOA TTL and MINIMUM, which we measured at 300 to 3,600 seconds across eight major DNS hosts. Well-behaved clients confirm the record on the authoritative nameservers before asking the CA to validate.

Can I do DNS-01 without giving an ACME client access to my DNS? Yes. CNAME _acme-challenge.example.com to a label in a separate zone and let the client write there. Your production zone then holds one static record that never changes, and a compromised ACME client cannot touch your MX or A records. This is exactly what custom-domain platforms ask your customers to do.

Why does my wildcard order validate one name and fail the other? A certificate covering both the apex and the wildcard needs two TXT records at the same _acme-challenge label at the same time. Automation that replaces rather than appends leaves only the second one, so the first identifier never validates.

Does a CAA record block DNS-01? Not by itself, but it can be made to. RFC 8657 adds validationmethods and accounturi parameters to CAA, so you can permit dns-01 only, or restrict issuance to a single ACME account. The CA/Browser Forum has made honouring them mandatory for all CAs from March 2027.

Want this handled for you? Start free with Domainee — 50 custom domains + 100 GB bandwidth, no card.