DNS challenge is in staging


The dns-01 challenge is in staging and is ready for your client tests. The dns-01 challenge is an implementation of a DNS-only domain validation from the ACME spec. If you’ve ever added some bits to a domain’s DNS records for another CA’s domain validation, it works similarly.

We had a previously busted version in staging for a bit, but this is the first version where we (the boulder development team for Let’s Encrypt) are pretty confident is correct.

There will, of course, be another thread when production support occurs. We don’t have a date for that right now, but community testing of the DNS challenge will help speed it up.

I’m pretty excited about this one and so is the rest of the team! DNS challenge has been a big request from a lot of folks here, some larger organizations that wanted to use Let’s Encrypt, and myself. We’re happy to be getting it out there.

(Oh, and, as a reminder, the staging API is at https://acme-staging.api.letsencrypt.org and can be pointed to by the letsencrypt client with the --staging flag. Test your stuff there!)

We need better Architecture

Hello @jmhodges,

Good news but seems there is no reference to this challenge nor documentation in official letsencrypt client. Do you know when we could test this new challenge using official letsencrypt client?.



There is an on-going PR to add the DNS challenge to the python acme library but, for the actual client, the answer is: for now, no.

Folks have previously argued it’s a little too complicated and un-automatable (since DNS providers don’t have a generic write API for the client to use) for the DNS challenge to go into the official client. On top of that, there’s some higher priority stuff needing to be done in the client than working out a robust way to do the DNS challenge well.


Many thanks for working hard to get this working, I’ve been testing on the staging server and can successfully verify domains using this DNS method and then issue certificates.

Is there an ETA as to when this is likely to hit production?


Can’t give an ETA publicly because it’ll depend on community testing. I know that’s annoying to hear but we’d rather not make promises in public (and they totally will be heard as promises by someone!) that we can’t keep.


and community testing depends on documentation for it too :wink:


For what it’s worth, lego is ready to support dns-01. A recent pull request also automates it for CloudFlare, AWS, and RFC 2136-compliant DNS providers. (I intend to submit a PR to add support for DigitalOcean, too – unless someone beats me to it.)

As soon as that lands in master, Caddy will also allow site owners to take advantage of the dns-01 challenge. I’ve had a lot of requests for it. So if I have the chance, I’ll definitely help test it.


Nice work!

Out of curiosity I played around with this a little bit this evening by jury rigging lego’s support far enough to have it function in another project. It looks like it almost worked, but the staging environment seems to have seen a DNS error that looks something like this:

{"type":"dns-01","status":"invalid","error":{"type":"urn:acme:error:connection","detail":"Server failure at resolver during TXT-record lookup of _acme-challenge.singularity.brandur.org"},"uri":"https://acme-staging.api.letsencrypt.org/acme/challenge/muCPwShQw...","token":"...","keyAuthorization":"..."}

Which looks like it happens when trying to resolve the TXT record and receiving a problem other than a timeout or network error:

For comparison, dig seems to find the added records without trouble:

$ dig TXT _acme-challenge.singularity.brandur.org

; <<>> DiG 9.8.3-P1 <<>> TXT _acme-challenge.singularity.brandur.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27330
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;_acme-challenge.singularity.brandur.org. IN TXT

_acme-challenge.singularity.brandur.org. 120 IN TXT "af1iV2ZYfCqfMDU-AwSstuk2Zkm66Ui4ZfAMvFJrY6g"
_acme-challenge.singularity.brandur.org. 120 IN TXT "9C0DqKC_4MkowIFByHhFaP8u0Zv4z7Wz2IHM91lTKec"

;; Query time: 39 msec
;; WHEN: Thu Jan  7 23:00:08 2016
;; MSG SIZE  rcvd: 169

It looks like there’s a debug message right below the line linked to above that might help dredge up the problem.


Funny, I have also been playing with lego and dns tonight as well. I got it working by adding a sleep of 10 seconds between adding the txt record and telling LE we are ready for the challenge. That is something lego can fix at some point. Join us in the lego gitter if you have more questions.


@captncraig I just tried your suggestion and it worked for me as well.

Although a client patch works, I suspect there may still be some boulder-related trouble here somewhere: I’m not so sure that the DNS failure is due to the ACME server not being able to find TXT records because even if there is a race, it should still be seeing the old TXT records from my previously failed challenge attempts that now contain bad digests.

Also, it might make sense for an ACME client to give a server a bit of grace time after provisioning a TXT record, but even if it doesn’t, the server may still want to keep trying for some time before invalidating the request. I notice that I get one “pending” message back, but the next one is immediately a failure.

Anyway, thanks for the help!


@brandur we do plan on doing a lookup ourselves in the final version before telling boulder we are ready.


FYI: With a pull request from today letsencrypt.sh also supports the dns-01 challenge.


The DNS challenge test is working for ACMESharp client lib as well now. The verification was happening a little too quick after the challenge submission, so I needed to introduce a slight artificial delay during the testing routines as well, but otherwise, works great.



Actually one peculiar thing I’ve found – ACMESharp currently supports handling dns-01 and http-01 challenge types. If I test Identifier validation with either DNS or HTTP challenge, the test is fine, but if I test with both challenge types against the same Identifier – whichever one I try to submit second fails with a 400 error from the server:

{"type":"urn:acme:error:malformed","detail":"Unable to update challenge :: Challenge data was corrupted","status":400}

Can anyone else confirm this, and is this expected behavior? I understand that the overall status of the Identifier changes to valid, but the individual challenge is still pending so I would think it would allow to submit and verify that challenge, no?


just a question: what will be put in the DNS? some random stuff or the account key? also does it affect subdomains?

it would be great if I could just post my acc key to the root and tell them that this account is allowed to do LE certs for this domain and subs.


@mjphaynes, since this is not in the official client yet…what client are you using to test, and how are you specifying that its a DNS challenge to the staging server?


Hello @ezeeetm,

I don’t know what client is using @mjphaynes but seems that letsencrypt.sh client implements dns challenge, just in case you would like to test it.



Tested and works with acme4j.


Using letsencrypt.sh and a small hook script I was able to use dns-01 without issue.

One question I have is what DNS sever is let’s encrypt hitting to get the TXT record? I’d like to verify the record shows up on that server before proceeding with the challenge. In testing I had to update the TXT record a few times and I initially used a TTL of 300, so there was a lot of old cached results floating around.


Let’s Encrypt does authoritative lookups (i.e. starting from root servers). You can simulate that with dig example.com +trace. Maximum TTL is limited to a few minutes on their end.