Simple Local Boulder/Certbot HTTP-01 Challenge

I am new. I want to get certbot and boulder working in a simple environment. They both run on the VM where I run the below command (http-01 challenge). I can’t tell if the challenge is getting routed by Boulder’s fake DNS server correctly. I have an endpoint at{whatever} listening for calls, but nothing has come in. I have done no editing to boulder or certbot files (maybe this is the problem).

My domain is: localhost

I ran this command: certbot certonly --server http://localhost:4001/directory --manual --preferred-challenges=http -d

It produced this output:

  • The following errors were reported by the server:

    Type: unauthorized
    Detail: The key authorization file from the server did not match
    this challenge
    != “”

    To fix these errors, please make sure that your domain name was
    entered correctly and the DNS A/AAAA record(s) for that domain
    contain(s) the right IP address.

The operating system my web server runs on is (include version): Ubuntu 16.04.6

I can login to a root shell on my machine (yes or no, or I don’t know): yes

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you’re using Certbot): certbot 0.31.0

Here is the response in the log:
“identifier”: {
“type”: “dns”,
“value”: “
“status”: “invalid”,
“expires”: “2020-02-07T20:40:05Z”,
“challenges”: [
“type”: “http-01”,
“status”: “invalid”,
“error”: {
“type”: “urn:ietf:params:acme:error:unauthorized”,
“detail”: “The key authorization file from the server did not match this challenge “z2WA2LyKkf_HVWtdNXp4BPVkWJsD4am5iE145mqEm-8.94bvla0zv_zrfHrERr00iaF6ahwEJ0Zv0g-OBUJcsqE” != “””,
“status”: 403
“url”: “http://localhost:4001/acme/chall-v3/18/PlC-6A”,
“token”: “z2WA2LyKkf_HVWtdNXp4BPVkWJsD4am5iE145mqEm-8”,
“validationRecord”: [
“url”: “”,
“hostname”: “”,
“port”: “5002”,
“addressesResolved”: [
“addressUsed”: “”

Maybe someone can explain the addressResolved and addressUsed attributes? It doesn’t seem to resolve to IP (which is what I would expect with no fake DNS), but it also isn’t

1 Like

These are the only changes I make to a clean copy of Boulder if I want to validate against a real domain:

diff --git a/test/config/va.json b/test/config/va.json
index ece66add..841b3a1e 100644
--- a/test/config/va.json
+++ b/test/config/va.json
@@ -3,15 +3,15 @@
     "userAgent": "boulder",
     "debugAddr": ":8004",
     "portConfig": {
-      "httpPort": 5002,
-      "httpsPort": 5001,
-      "tlsPort": 5001
+      "httpPort": 80,
+      "httpsPort": 443,
+      "tlsPort": 443
     "maxConcurrentRPCServerRequests": 100000,
     "dnsTries": 3,
     "dnsResolvers": [
-      "",
-      ""
+      "",
+      ""
     "issuerDomain": "happy-hacker-ca.invalid",
     "tls": {
@@ -38,7 +38,7 @@

   "common": {
-    "dnsTimeout": "1s",
+    "dnsTimeout": "10s",
     "dnsAllowLoopbackAddresses": true

Have you done something similar already?


No, I’m not trying to validate a real domain. Everything is on localhost. I want to see a successful HTTP-01 challenge. I expect the domain I put in to be ignored and for Boulder to redirect to for the challenge. So I have a server listening at I expect this to be called when certbot gives this message:

Create a file containing just this data:


And make it available on your web server at this URL:

1 Like

Well, refers to loopback inside the Docker container, not on the Docker host.

So from Boulder’s perspective, nobody is listening on

I think you will want to get the IP address of docker0 on your host, and replace the FAKE_DNS environment variable in docker-compose.json with that IPv4 address.

You might still also need to update the HTTP port to 80 in va.json.


:wave: Hi @ryanesch

Are you running Boulder in Docker per the dev setup instructions? If so then the FAKE_DNS value shouldn’t be, it should be the IP of your host machine’s docker interface.

This would be the error I would expect to see if the FAKE_DNS was and your ACME client was on the Docker host. The empty key auth response would be from the pebble-challtestsrv running on in the Boulder docker container and not the webserver your ACME client provisioned the HTTP-01 response with.

P.s. Have you considered using Pebble instead of Boulder? It’s generally much easier to work with.


Thank you for the reply! You and _az were spot on. The problem was my FAKE_DNS pointing inside my docker container instead of the bridge to my host machine. After I changed FAKE_DNS and httpport in va.json, I got this working.
Thanks again.


Glad to hear it! Thanks for reporting back with the fix that worked.

1 Like