← Back to blog

_acme-challenge TXT Record: DNS-01 Explained and Fixed

Domainee·
acme challengeacme-challenge_acme-challengedns-01 challenge_acme-challenge txt record
_acme-challenge TXT Record: DNS-01 Explained and Fixed

The _acme-challenge TXT record is a DNS record at _acme-challenge.<your-domain> that proves to a certificate authority (CA) that you control that domain's DNS. It is the proof used by the ACME DNS-01 challenge. The CA gives your client a token, your client publishes it as a TXT value, the CA looks it up, and the certificate gets issued.

It is temporary proof, not a permanent setting. Once the certificate is issued, you can usually delete the record. The next renewal creates a fresh one. Below: how the challenge works, why the record shows up on your domain, a troubleshooting flow you can paste into a terminal, and what changes when the DNS belongs to your customers.

What is the _acme-challenge TXT record?

It is a plain TXT record with a predictable name and a random-looking value.

FieldValue
Name_acme-challenge.example.com
TypeTXT
ValueA token-derived string from the CA flow (typically 43 characters, base64url)
TTLShort is better. 60 to 300 seconds

In a zone file:

_acme-challenge.example.com. 300 IN TXT "gfj9Xq...Rg85nM"

Or as the JSON that most DNS provider APIs want:

{
  "type": "TXT",
  "name": "_acme-challenge",
  "content": "gfj9Xq...Rg85nM",
  "ttl": 300
}

The leading underscore keeps the name out of the way of real hostnames. The value is not a secret and not a password. It is a fingerprint the CA can recompute and compare. For definitions, see the ACME protocol glossary entry.

How the DNS-01 challenge works, step by step

The ACME protocol is defined in RFC 8555. DNS-01 is one of its challenge types. The flow:

  1. Your client asks the CA for a certificate for example.com.
  2. The CA replies with a challenge token for that name.
  3. Your client combines the token with your ACME account key and hashes it. That is the TXT value.
  4. Your client publishes the value at _acme-challenge.example.com.
  5. The CA queries DNS for that name and checks the value.
  6. If it matches, the CA issues the certificate.
  7. Your client removes the record (good clients do; many don't).

As a diagram:

client --(1) order cert-----------> CA
client <-(2) challenge token------- CA
client --(3) publish TXT----------> your DNS
CA     --(4) query TXT------------> your DNS
client <-(5) certificate issued---- CA

Notice what is missing: nothing has to reach your web server. The CA only talks to DNS. That is the whole appeal.

DNS-01 vs HTTP-01 vs TLS-ALPN-01: when DNS-01 is the right one

DNS-01HTTP-01TLS-ALPN-01
What it provesControl of the domain's DNSControl of a web server answering for the nameControl of a TLS server answering for the name
Needs inbound portNonePort 80Port 443
Wildcard certificatesYesNoNo
Works behind a firewallYes, since the CA never connects to youOnly if port 80 is reachableOnly if port 443 is reachable
Needs DNS write accessYesNoNo

Pick DNS-01 when you need a wildcard, when the server is not reachable from the internet, or when one machine issues certificates for many others. The price is DNS write access, and that is where most of the pain comes from. For background on wildcards, read about wildcard SSL certificates.

Pick HTTP-01 when you have a public web server on port 80 and no wildcard requirement. It needs no DNS credentials at all.

Can I delete the _acme-challenge record? Why is it on my domain?

If you found a stray _acme-challenge TXT record, a tool added it. Probably certbot, acme.sh, a hosting panel, a CDN, or a script someone wrote on a Tuesday and forgot. Clients are supposed to clean up after issuance. Some don't, especially after a failed run.

A TXT record at that name is generally safe to delete after the certificate is issued. The certificate does not depend on it. The next renewal publishes a new value.

Two cases where you should stop and look first:

  • A deliberate CNAME. If _acme-challenge is a CNAME pointing to another zone, someone set up delegation on purpose. Deleting it breaks renewals. (More on this below.)
  • An automated client that expects the record. Most clients create what they need, but some setups pre-provision records. Check what created it, then delete it.

Fast sanity check: if the certificate for that name was issued recently and renewal is automated, delete the stale TXT. If you don't know what issues certificates for the domain, find that out first.

Troubleshooting the _acme-challenge TXT record

Start with what is actually published:

dig TXT _acme-challenge.example.com +short

No dig? Use the free TXT record lookup. It needs no API key. The public API behind it allows 30 requests a minute and 500 a day per IP, which is plenty for debugging.

Then query the authoritative nameservers directly, so resolver caches can't lie to you:

dig NS example.com +short
dig @ns1.your-dns-provider.com TXT _acme-challenge.example.com +short

If the answer from the authoritative server is right and the answer from your resolver is wrong, you have a caching problem. If the authoritative answer is wrong, the record was never published where it counts.

Failure causes, in the order they bite

CauseSymptomConfirmFix
Not published yet, or propagation lagCA says no TXT record found; dig returns nothingdig TXT _acme-challenge.example.com +short against the authoritative serverWait, then retry. Make your client pause before asking the CA to validate
Doubled domain suffixRecord exists at _acme-challenge.example.com.example.comdig TXT _acme-challenge.example.com.example.com +short returns your valueRegistrar UIs often append the domain. Enter only _acme-challenge as the host
Stale value from a previous attemptCA reports a value mismatchCompare the dig output with what your client says it publishedDelete the old value, publish the new one
Multiple TXT values at one nameIntermittent success or confusing mismatchesdig returns two or more linesRemove values that aren't from the current order. Legitimate exception: a wildcard plus apex certificate needs two values at the same name
High TTL caching an old answerAuthoritative server is right, your resolver is wrongCompare dig @authoritative against plain digUse a TTL of 60 to 300 seconds for challenge records. See DNS TTL
CNAME at _acme-challenge conflicting with a TXTYour provider refuses the TXT, or the CNAME winsdig CNAME _acme-challenge.example.com +shortA name can't hold a CNAME and a TXT. Pick one: delegate with the CNAME, or publish TXT and remove the CNAME
Wrong DNS provider or nameserversRecord visible in your dashboard, not in digdig NS example.com +short shows a different provider than the one you editedEdit DNS where the domain's NS records actually point
CAA record blocking the CAValidation passes, issuance is refuseddig CAA example.com +shortAdd an issue entry for your CA (for Let's Encrypt, letsencrypt.org), plus issuewild for wildcards

Propagation is the most common culprit and the most misdiagnosed. If you want a second opinion across resolvers, run the name through the free DNS propagation checker.

Rate limits turn a typo into an hour of waiting

CAs rate-limit failed validations. Let's Encrypt, for example, limits failed validation attempts per hostname per account per hour (the docs list 5 at the time of writing). Retry in a tight loop with a doubled suffix and you will lock yourself out for a while. Confirm current numbers in the Let's Encrypt rate limit docs before you build retry logic around them. Better: check with dig first, then retry once.

Wildcards, delegation and automation

Wildcards need DNS-01. HTTP-01 and TLS-ALPN-01 can't validate *.example.com. If you want one certificate for every subdomain, you are publishing TXT records.

CNAME delegation is the common way to avoid handing a client your whole DNS account. You add a one-time CNAME:

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

The CA follows the CNAME and reads the TXT record from a zone you control for that purpose. Your client then only needs write access to that small zone. The main domain stays untouched. Verify the exact behavior in the Let's Encrypt challenge-types docs for your client.

Scope your DNS API tokens to the minimum. A token that can edit every zone in your account is a bad thing to leave in a cron job. Limit it to one zone, or better, to the delegated validation zone. Limit it to TXT edits if your provider supports that.

The multi-tenant problem: when the DNS is your customer's

Everything above assumes you own the DNS. If your SaaS lets users bring their own domain, you don't.

You can't add the TXT record yourself. You can't fix a doubled suffix. You can't check which provider is really serving the zone. Every failed challenge becomes a support ticket, and your customer has to be a DNS person to answer it.

This is the part that eats roadmaps. A weekend feature turns into ACME rate limits, edge TLS termination, SNI routing, DNS health checks and certificate rotation. That is 2 to 4 months of v1, plus ongoing on-call for cert outages.

This is what Domainee handles. Domainee is a custom-domains-as-a-service API for SaaS products. Automatic SSL for custom domains is issued through Let's Encrypt on the first request and renewed automatically. Your customer needs one CNAME, not a registrar account or DNS expertise.

Create a domain with one call:

curl https://api.domainee.dev/v1/domains \
  -H "Authorization: Bearer sk_live_..." \
  -H "Idempotency-Key: 7f3c2a10-signup-acme" \
  -H "Content-Type: application/json" \
  -d '{"hostname": "app.customer.com", "originUrl": "https://your-app.example.com"}'

The response includes the CNAME your customer adds. Status and DNS state come back as status and monitorStatus (abridged, illustrative):

{
  "id": "dom_...",
  "hostname": "app.customer.com",
  "monitorStatus": "dns_not_resolving"
}

Each domain is re-checked every 5 minutes, or on demand with POST /v1/domains/{id}/check. The monitor states tell you where a domain is stuck:

  • unknown: not checked yet.
  • dns_not_resolving: the hostname doesn't resolve yet.
  • dns_incorrect: it resolves, but not to the right target.
  • pending_ssl: DNS is fine, the certificate is on its way.
  • active_ssl: done.
  • ssl_failed and ssl_expired: the ones you want a webhook for.

Webhooks cover domain.verified, domain.failed, domain.expired and domain.monitor_updated, signed with HMAC-SHA256 in the x-domainee-signature header. Preflight also warns on CAA records that block Let's Encrypt, which is the last cause in the table above, caught before your customer files a ticket.

Domainee by Common Ninja runs in production for Common Ninja, Embeddable and Vidocu. Pricing is published: 20 domains and 100 GB a month free, forever. After that it's $0.20 per domain per month, and bandwidth is $0.05/GB above 100 GB. A card on file is required before the first domain and is charged $0 under the free tier.

FAQ

What is the _acme-challenge TXT record? A TXT record at _acme-challenge.<domain> that proves to a CA that you control the domain's DNS. It is used by the ACME DNS-01 challenge and is temporary.

What is the ACME DNS-01 challenge? It is the ACME challenge type where you prove control of a domain by publishing a CA-supplied value as a TXT record in its DNS. It is the only one of the three common types that supports wildcard certificates.

Why is there an _acme-challenge record on my domain? A certificate client, hosting panel, CDN or script added it during issuance or renewal. Clients are supposed to clean up, and some don't, especially after a failed run.

Can I delete the _acme-challenge TXT record? Usually yes, after the certificate is issued. Check first that it isn't a deliberate CNAME delegation and that no automated client depends on it.

How do I add an _acme-challenge TXT record? Create a TXT record with the host _acme-challenge (not the full domain, or you will double the suffix) and the value your client prints. Use a short TTL, then confirm with dig before telling the CA to validate.

Why is my DNS-01 challenge failing? Usually the record isn't published yet, sits at the wrong name, carries a stale value, or was added at a DNS provider that doesn't serve the domain. The troubleshooting table above lists the checks in order.

How long does an _acme-challenge TXT record take to propagate? It depends on your DNS provider and the TTL of any cached answer. Query the authoritative nameserver directly to see whether the record is live, then wait out any resolver cache.

Do I need DNS-01 for wildcard certificates? Yes. HTTP-01 and TLS-ALPN-01 can't validate wildcard names.

What is the difference between HTTP-01 and DNS-01? HTTP-01 proves control of a web server on port 80. DNS-01 proves control of the domain's DNS, needs no open port, and supports wildcards, but requires DNS write access.

Can I use a CNAME for _acme-challenge? Yes. Delegating _acme-challenge to a zone you control is a common pattern. A name can't hold both a CNAME and a TXT record.

Can there be more than one _acme-challenge TXT record at the same name? Yes, and sometimes it's required, for example a wildcard plus apex certificate. Stale values from old attempts are what cause trouble, so remove those.

How do I check an _acme-challenge record with dig? Run dig TXT _acme-challenge.example.com +short. Query the authoritative nameserver with dig @ns1.example.net TXT _acme-challenge.example.com +short to bypass caches.

Check what is actually published

Run your domain through the free TXT record lookup to see what is published at _acme-challenge. If you would rather never debug a customer's DNS at 2am, create a Domainee account and connect your first domain with one API call. 20 domains are free, forever.