DNS Challenge - Namecheap API

SOLVED: LOOK AT BOTTOM OF THIS POST

1. The problem I’m having:

I’m trying to get ACME to issue certificates using the DNS challenge, but no matter what I try, I can’t get it to find the domain name. I’m currently doing this in the Namecheap Sandbox API.

I’ve been beating my head and can’t figure this out. I’m still relatively new to Caddy and web hosting.

2. Error messages and/or full log output:

caddy  | {"level":"info","ts":1720719819.2124565,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
caddy  | {"level":"info","ts":1720719819.213755,"msg":"adapted config to JSON","adapter":"caddyfile"}
caddy  | {"level":"warn","ts":1720719819.2137642,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
caddy  | {"level":"info","ts":1720719819.2145677,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
caddy  | {"level":"info","ts":1720719819.2147474,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
caddy  | {"level":"info","ts":1720719819.2147918,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
caddy  | {"level":"info","ts":1720719819.214749,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0000a7b80"}
caddy  | {"level":"info","ts":1720719819.2152846,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
caddy  | {"level":"info","ts":1720719819.2153451,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
caddy  | {"level":"info","ts":1720719819.215469,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy  | {"level":"info","ts":1720719819.215508,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
caddy  | {"level":"info","ts":1720719819.2155128,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["*.famdam.com"]}
caddy  | {"level":"info","ts":1720719819.215729,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy  | {"level":"info","ts":1720719819.2158089,"msg":"serving initial configuration"}
caddy  | {"level":"info","ts":1720719819.2159202,"logger":"tls.obtain","msg":"acquiring lock","identifier":"*.famdam.com"}
caddy  | {"level":"info","ts":1720719819.217455,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/data/caddy"}
caddy  | {"level":"info","ts":1720719819.2189858,"logger":"tls.obtain","msg":"lock acquired","identifier":"*.famdam.com"}
caddy  | {"level":"info","ts":1720719819.2191768,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"*.famdam.com"}
caddy  | {"level":"info","ts":1720719819.2198956,"logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["*.famdam.com"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
caddy  | {"level":"info","ts":1720719819.219907,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["*.famdam.com"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
caddy  | {"level":"info","ts":1720719819.2199156,"logger":"tls.issuance.acme","msg":"using ACME account","account_id":"https://acme-v02.api.letsencrypt.org/acme/acct/1746453062","account_contact":[]}
caddy  | {"level":"info","ts":1720719819.2205517,"logger":"tls","msg":"finished cleaning storage units"}
caddy  | {"level":"info","ts":1720719819.8091974,"logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"*.famdam.com","challenge_type":"dns-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
caddy  | {"level":"error","ts":1720719820.2281828,"logger":"tls.issuance.acme.acme_client","msg":"cleaning up solver","identifier":"*.famdam.com","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.famdam.com\" (usually OK if presenting also failed)"}
caddy  | {"level":"error","ts":1720719820.316882,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"*.famdam.com","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[*.famdam.com] solving challenges: presenting for challenge: adding temporary record for zone \"_acme-challenge.famdam.com.\": namecheap api returned error in response. Err: Error0: Domain name not found\t (order=https://acme-v02.api.letsencrypt.org/acme/order/1746453062/286386154437) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
caddy  | {"level":"error","ts":1720719820.3170543,"logger":"tls.obtain","msg":"will retry","error":"[*.famdam.com] Obtain: [*.famdam.com] solving challenges: presenting for challenge: adding temporary record for zone \"_acme-challenge.famdam.com.\": namecheap api returned error in response. Err: Error0: Domain name not found\t (order=https://acme-v02.api.letsencrypt.org/acme/order/1746453062/286386154437) (ca=https://acme-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":1.098055501,"max_duration":2592000}

3. Caddy version:

v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

4. How I installed and ran Caddy:

xcaddy build --with github.com/caddy-dns/namecheap --with github.com/mholt/caddy-dynamicdns

a. System environment:

Arch Linux using Linux-LTS kernel, x86_64
Docker and Docker Compose

b. Command:

sudo docker compose up -d

c. Service/unit/compose file:

services:

  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE #optional
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Boise
      - SERVERURL=wireguard.public-4rknm.duckdns.org
      - SERVERPORT=51820 #optional
      - PEERS={REDACTED}
      - PEERDNS=172.50.0.3 #optional
      - INTERNAL_SUBNET=10.13.13.0 #optional
      - ALLOWEDIPS=0.0.0.0/0 #optional
      - PERSISTENTKEEPALIVE_PEERS=all #optional
      - LOG_CONFS=true #optional
    volumes:
      - ./wireguard/config:/config
    ports:
      - 51820:51820/udp
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped
    depends_on:
      - unbound
      - pihole
    networks:
      caddy_net: {}
      dns:

  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - 127.0.0.1:53:53/tcp
      - 192.168.1.60:53:53/udp # Only works when assigned local IP
    environment:
      DNSMASQ_LISTENING: all
      TZ: America/Boise
      VIRTUAL_HOST: pihole.4rknm.duckdns.org
      WEBPASSWORD: {REDACTED}
      FTLCONF_LOCAL_IPV4: 192.168.1.60
      WEBTHEME: default-dark
    volumes:
      - ./pihole/etc-pihole:/etc/pihole
      - ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d
      - ./pihole/logs:/var/log/pihole/pihole_debug.log
    cap_add:
      - NET_ADMIN
    restart: unless-stopped
    depends_on:
      - unbound
      - caddy
    networks:
      dns:
      caddy_net: {}

  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vaultwarden.4rknm.duckdns.org"
      YUBICO_CLIENT_ID: "{REDACTED}"
      YUBICO_SECRET_KEY: "{REDACTED}"
    volumes:
      - ./vaultwarden/vw-data:/data
    networks:
      caddy_net: {}

  fail2ban:
    image: crazymax/fail2ban:latest
    container_name: fail2ban
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - NET_RAW
    network_mode: host
    environment:
      - TZ=America/Boise
      - F2B_DB_PURGE_AGE=30d
      - F2B_LOG_TARGET=STDOUT
      - F2B_LOG_LEVEL=INFO
      - F2B_IPTABLES_CHAIN=INPUT
      - PUID=1000
      - PGID=1000
      - VERBOSITY=-vv #optional
    volumes:
      - ./fail2ban/config:/config
      - ./fail2ban:/data
      - ./fail2ban/log:/log:ro
      - ./vaultwarden/vw-data/log:/remotelogs/vaultwarden:ro
      - ./caddy/caddy-data/access.log:/remotelogs/caddy:ro
      - ./teamspeak/logs:/remotelogs/teamspeak:ro
      - ./nextcloud/nextcloud.log:/remotelogs/nextcloud:ro

  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
      - 443:443/udp # Needed for HTTP/3.
    volumes:
      - ./caddy/caddy:/usr/bin/caddy  # Your custom build of Caddy.
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/caddy-config:/config
      - ./caddy/caddy-data:/data
    environment:
      EMAIL: "rileymotter@protonmail.com"
      NAMECHEAP_API_USER: "Rettom"
      NAMECHEAP_API_KEY: "f4703c2377ee44ff8bda50e01c039b44"
      LOG_FILE: "/data/access.log"
    extra_hosts: ["host.docker.internal:host-gateway"]
    networks:
      caddy_net: {}

  unbound:
    container_name: unbound
    image: "mvance/unbound:latest"
    networks:
      dns:
        ipv4_address: 172.50.0.2
    volumes:
      - "./unbound/forward-records.conf:/opt/unbound/etc/unbound/forward-records.con>
      - "./unbound/a-records.conf:/opt/unbound/etc/unbound/a-records.conf"
      - type: bind
        read_only: true
        source: ./unbound/unbound.conf
        target: /opt/unbound/etc/unbound/unbound.conf
    restart: unless-stopped

  teamspeak:
    image: teamspeak
    restart: unless-stopped
    ports:
      - 9987:9987/udp # Voice service
      - 30033:30033   # File transfer
      - 41144:41144   # DNS domain resolution (optional)
      - 10011:10011   # Server query raw (optional)
      # - 10022:10022   # Server query SSH (optional)
      # - 10080:10080   # Network request http (optional)
      # - 10443:10443   # Network request https (optional)
    environment:
      TS3SERVER_DB_PLUGIN: ts3db_mariadb
      TS3SERVER_DB_SQLCREATEPATH: create_mariadb
      TS3SERVER_DB_HOST: db-ts
      TS3SERVER_DB_USER: root
      TS3SERVER_DB_PASSWORD: {REDACTED}
      TS3SERVER_DB_NAME: teamspeak
      TS3SERVER_DB_WAITUNTILREADY: 30
      TS3SERVER_LICENSE: accept
    volumes:
      - ./teamspeak:/var/ts3server
    networks:
      teamspeak:
  db-ts:
    image: mariadb
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: UBKgZRQwjg68pP^8K7wR3wv4TRuNzSh&NfrtQzJDkw8f5Pq3
      MYSQL_DATABASE: teamspeak
    volumes:
      - ./mysql/teamspeak:/var/lib/mysql  # Required, otherwise data will be lost af>
    networks:
      teamspeak:

  nextcloud:
    image: nextcloud/all-in-one:latest
    init: true
    restart: unless-stopped
    container_name: nextcloud-aio-mastercontainer
    ports:
      - 8080:8080
    volumes:
      - nextcloud_aio_mastercontainer:/mnt/docker-aio-config
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      APACHE_PORT: 11000 #
      APACHE_IP_BINDING: 0.0.0.0 # Should be set when running behind a web server or>
      # BORG_RETENTION_POLICY: --keep-within=7d --keep-weekly=4 --keep-monthly=6
      NEXTCLOUD_DATADIR: ./nextcloud
      NEXTCLOUD_UPLOAD_LIMIT: 10G
      NEXTCLOUD_MAX_TIME: 3600
      NEXTCLOUD_MEMORY_LIMIT: 1024M # Can be adjusted if you need more. See https://>
    networks:
      caddy_net: {}

  watchtower:
    image: containrrr/watchtower
    environment:
      - TZ=America/Boise
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock


networks:
  caddy_net:
    external: true
  dns:
    ipam:
      config:
        - subnet: 172.50.0.0/16
  teamspeak:
  nextcloud:

volumes:
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer

d. My complete Caddy config:

*.famdam.com {

    tls {
         dns namecheap {
           api_key {$NAMECHEAP_API_KEY}
           user {$NAMECHEAP_API_USER}
           api_endpoint https://api.sandbox.namecheap.com/xml.response
           client_ip 139.60.65.236
         }
    }

        @wireguard host wireguard.famdam.top
        handle @wireguard {
            reverse_proxy wireguard:80
        }

        @teamspeak host teamspeak.famdam.top
        handle @teamspeak {
            reverse_proxy teamspeak:80
        }

        @vaultwarden host vaultwarden.famdam.top
        handle @vaultwarden {
            reverse_proxy vaultwarden:80
        }

        @pihole host pihole.famdam.top
        handle @pihole {
            reverse_proxy pihole:80
        }

        @nextcloud-aio-mastercontainer host nextcloud.famdam.top
        handle @nextcloud-aio-mastercontainer {
            reverse_proxy host.docker.internal:11000
        }

        # Fallback for otherwise unhandled domains
        handle {
                abort
        }
        # This setting may have compatibility issues with some browsers
        # (e.g., attachment downloading on Firefox). Try disabling this
        # if you encounter issues.
        encode zstd gzip
}

5. Links to relevant resources:

Solution was posted here much later:

@TheRettom for the issues with the namecheap dns challenge plugin: DNS Challenge - Namecheap API You’re pointed at the sandbox api_endpoint instead of production ( See Intro to API for Developers | Namecheap.com ), it only allows you to do it for domains it sees you as owning which is why the namecheap api gives back an error about the domain not being found in your log.
Also make sure your other info (api_key, user) are production account values as well.

Hi @TheRettom,

Not sure but this might be close

I’m thinking this isn’t the exact problem, but if it comes down to it, I’ll abandon the Namecheap API in favor of something that clearly works better. I appreciate you linking that.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.

An updated answer has been posted here:

1 Like