DNS challenge no memory error

1. Output of caddy version:

caddy:2

2. How I run Caddy:

via docker-compose file

a. System environment:

WSL2 with Ubuntu 20.4

b. Command:

docker compose up -d

c. Service/unit/compose file:

version: '3'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    environment:
      WEBSOCKET_ENABLED: "true"  # Enable WebSocket notifications.
#      DOMAIN: "https://ubuntu22"
      SIGNUPS_ALLOWED: "false"
      INVITATIONS_ALLOWED:  "false"
      LOG_LEVEL: "warn"
#      DOMAIN: "localhost"
      SMTP_HOST: "smtp.google.com"
      SMTP_FROM: "myemail"
      SMTP_PORT: "587"
      SMTP_SECURITY: "starttls"
      SMTP_USERNAME: "myemail"
      SMTP_PASSWORD: "nothing"

    volumes:
      - ./vw-data:/data

  caddy:
    image: caddy:2
    container_name: caddy
    restart: always
    ports:
      - 80:80  # Needed for the ACME HTTP-01 challenge.
      - 443:443
    volumes:
      - ./caddy:/usr/bin/caddy      #  Your custom build of Caddy
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-config:/config
      - ./caddy-data:/data

    environment:
      DOMAIN: "subdomain.duckdns.org"      # Your domain.
      EMAIL: "zung102@yahoo.com"            # The email address to use for ACME registration.
      DUCKDNS_TOKEN: "token taken from duckdns website"
      LOG_FILE: "/data/access.log"

d. My complete Caddy config:

{$DOMAIN}:443 {

  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }

  # Use the ACME HTTP-01 challenge to get a cert for the configured domain.
 #  tls zung102@yahoo.com
  tls {
    dns duckdns {$DUCKDNS_TOKEN}
  }
  # This setting may have compatibility issues with some browsers
  # (e.g., attachment downloading on Firefox). Try disabling this
  # if you encounter issues.
  encode gzip


  header {
       # Enable cross-site filter (XSS) and tell browser to block detected attacks
       X-XSS-Protection "1; mode=block"
       # Disallow the site to be rendered within a frame (clickjacking protection)
       X-Frame-Options "DENY"
       # Prevent search engines from indexing (optional)
       X-Robots-Tag "none"

  }

  # Notifications redirected to the WebSocket server


# The negotiation endpoint is also proxied to Rocket
  reverse_proxy /notifications/hub/negotiate vaultwarden:80
# Notifications redirected to the websockets server
  reverse_proxy /notifications/hub vaultwarden:3012
# Proxy everything else to Rocket
  reverse_proxy  vaultwarden:80 {
       # Send the true remote IP to Rocket, so that vaultwarden can put this in the
       # log, so that fail2ban can ban the correct IP.
       header_up X-Real-IP {remote_host}
  }
]

3. The problem I’m having:

Starting up vaultwarden and caddy services with this command
docker compose up -d

vaultwarden log showed no error.
Caddy log showed errors trying to obtain the certificates.

Below was the resultsof curl command …

zung@Dzungabc:~/vaultwarden$ curl -v 172.20.0.2

  • Trying 172.20.0.2:80…
  • TCP_NODELAY set

that was all the command produced for vaultwarden interface… same for Caddy network interface.

4. Error messages and/or full log output:

2023-01-19 13:34:12 {"level":"info","ts":1674153252.1390576,"logger":"http","msg":"waiting on internal rate limiter","identifiers":["new.vfor25.duckdns.org"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"zung102@yahoo.com"}
2023-01-19 13:34:12 {"level":"info","ts":1674153252.1391258,"logger":"http","msg":"done waiting on internal rate limiter","identifiers":["new.vfor25.duckdns.org"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"zung102@yahoo.com"}
2023-01-19 13:34:12 {"level":"info","ts":1674153252.9048848,"logger":"http.acme_client","msg":"trying to solve challenge","identifier":"new.vfor25.duckdns.org","challenge_type":"dns-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
2023-01-19 13:34:12 {"level":"error","ts":1674153252.941441,"logger":"http.acme_client","msg":"cleaning up solver","identifier":"new.vfor25.duckdns.org","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.new.vfor25.duckdns.org\" (usually OK if presenting also failed)"}
2023-01-19 13:34:13 {"level":"error","ts":1674153253.0403888,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"new.vfor25.duckdns.org","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[new.vfor25.duckdns.org] solving challenges: presenting for challenge: could not determine zone for domain \"_acme-challenge.new.vfor25.duckdns.org\": could not find the start of authority for _acme-challenge.new.vfor25.duckdns.org.: NOERROR (order=https://acme-v02.api.letsencrypt.org/acme/order/914577057/159805968087) (ca=https://acme-v02.api.letsencrypt.org/directory)"}

5. What I already tried:

I have almost identical setup in a PC with native Ubuntu22.04 and it was successful for both Vaultwarden and Caddy

6. Links to relevant resources:

I do not understand the meanings of the errors. Any help is really appreciated.

The ifconfig command should show Docker network interface too?
Here are the results from WSL2 …

 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.19.154.7  netmask 255.255.240.0  broadcast 172.19.159.255
        inet6 fe80::215:5dff:fe2e:eabc  prefixlen 64  scopeid 0x20<link>
        ether 00:15:5d:2e:ea:bc  txqueuelen 1000  (Ethernet)
        RX packets 17858  bytes 2619064 (2.6 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 106  bytes 7240 (7.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

if it supposed to show Docker and/or bridge interfaces, how can we get them back?

I have shutdowned wsl and started it up again without any improvement.

I have reduced the scenario like this …Caddyfile

my-new.duckdns.org:443 {
  #  tls zung102@yahoo.com
  tls {
    dns duckdns {token taken from duckdns.org}  # $DUCKDNS_TOKEN}
  }
  # Notifications redirected to the WebSocket server
  reverse_proxy /notifications/hub localhost:3012  

  # Proxy everything else to Rocket
  reverse_proxy localhost:8080
}

and then: docker run
below is the caddy log showing error…

2023/01/22 04:10:41.719 INFO    http    enabling automatic TLS certificate management   {"domains": ["my-new..duckdns.org"]}
2023/01/22 04:10:41.723 INFO    autosaved config (load with --resume flag)      {"file": "/root/.config/caddy/autosave.json"}
2023/01/22 04:10:41.723 INFO    serving initial configuration
2023/01/22 04:10:41.726 INFO    tls.obtain      acquiring lock  {"identifier": "my-new..duckdns.org"}
2023/01/22 04:10:41.742 INFO    tls.obtain      lock acquired   {"identifier": "my-new.duckdns.org"}
2023/01/22 04:10:41.743 INFO    tls.obtain      obtaining certificate   {"identifier": "my-new.duckdns.org"}
2023/01/22 04:10:42.635 INFO    http    waiting on internal rate limiter        {"identifiers": ["my-new.duckdns.org"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": ""}
2023/01/22 04:10:42.635 INFO    http    done waiting on internal rate limiter   {"identifiers": ["my-new.duckdns.org"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": ""}
2023/01/22 04:10:42.957 INFO    http.acme_client        trying to solve challenge       {"identifier": "my-new.duckdns.org", "challenge_type": "dns-01", "ca": "https://acme-v02.api.letsencrypt.org/directory"}
2023/01/22 04:10:43.287 ERROR   http.acme_client        cleaning up solver      {"identifier": "my-new.duckdns.org", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for \"_acme-challenge.my-new.duckdns.org\" (usually OK if presenting also failed)"}
2023/01/22 04:10:43.382 ERROR   tls.obtain      could not get certificate from issuer   {"identifier": "my-new.duckdns.org", "issuer": "acme-v02.api.letsencrypt.org-directory", "error": "[my-new.duckdns.org] solving challenges: presenting for challenge: adding temporary record for zone \"duckdns.org.\": DuckDNS request failed, expected (OK) but got (KO), url: [https://www.duckdns.org/update?domains=my-new.duckdns.org&token=&txt=Qzlalq8BcdNpR84lftCJ6DNcFyAhV4xhjtlcNqFTQ-A&verbose=true], body: KO (order=https://acme-v02.api.letsencrypt.org/acme/order/927944077/160270685317) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
2023/01/22 04:10:43.383 WARN    tls.issuance.zerossl    missing email address for ZeroSSL; it is strongly recommended to set one for next time

That implies that your token is incorrect.

The token is simply a UUID, you should only have letters, numbers and dashes in it and no other special characters.

You could use a placeholder to pull the value from an environment variable, but it doesn’t seem to be the case from your config.

Thank you … for looking into this problem.

I knew by now the token was not valid. But these errors only occurred when running Caddy docker as container within WSL/Ubuntu20.4. When I ran Caddy by command with the same token (from WSL/Ubuntu20.4) it worked fine. The same is true if I invoked caddy container from a standalone Ubuntu PC. Somehow the errors occurred only in WSL+Docker Desktop.

For lack of any possible solution, I am thinking about installing Docker within WSL and do not rely on Docker Desktop.

I can run caddy command but how is the Caddyfile looks like? what is the reverse-proxy to “localhost:80” ? where can I find caddy network ip to set up the forwarding from Windows host?

Do you have other suggestions?

Personally, I just run Caddy directly on Windows as a service. I’m not using Docker on Windows because it’s a Linux-native tool, and has significant overhead on Windows from running inside a Linux VM (via Hyper-V).

But I do often use Caddy in Docker when running apps in a Linux machine.

Keep in mind that when running in Docker “localhost” means “this container”. So you need to use the service name when trying to proxy to another container. Like reverse_proxy vaultwarden:8080 for example.

Thank you very much for your help. I have learnt a few things from you.

I have resolve the issue and got vaultwarden and caddy working as expected.

I still use the docker from Docker Desktop. The culprit is the way this docker reads the Caddyfile. The Duckdns token must be surrounded by quote. Using $DOMAIN environment variable was not helping either. The error messages were not clear. This led me to a wild chase.

Again, thank you for your help

It doesn’t, actually. It’s only necessary if there’s a space in the value. And DuckDNS tokens do not. See the docs:

What errors? What were you confused about?

I had used the token without quotes, in brackets or environment replacement $DUCKDNS_TOKEN: “123eddsd-322323-43434-54sr4545x” in Caddyfile

tls duckdns {$DUCKDNS_TOKEN} or
tls duckdns $DUCKDNS_TOKEN

They all gave error “no memory of presenting a DNS record…” until I hard-coded the token surrounded by double-quotes. This only happened in WSL environment. I had no issue with standalone Ubuntu PC.

The said error message made sense now by to a novice like me it implied a shortage of RAM.

When you declare an environment variable, you should not use a $.

When you use it in the Caddyfile, you must use braces and a $.

See the docs:

Ah, fair enough. It essentially means “I don’t remember having set a DNS record”. I see now how “memory” could be confusing.