Wildcard certificate issue - unable to determine authoritative nameserver

Hello y'all! I am running into an issue with getting a wildcard certificate generated for my subdomains, and I'm sure I'm just not configuring something correctly; any help or advice on what I'm doing wrong is greatly appreciated!

Traefik is running as a Docker container, alongside many other services. These services are accessed via subdomains off my personal domain internally. Here's the basic DNS records created in DigitalOcean:

On my home network there's a PiHole which has the custom DNS entries to redirect the subdomains to the appropriate box internally.

When Traefik starts up I can see log lines which indicate it is attempting to generate a certificate for the different subdomains:

DBG github.com/go-acme/lego/v4@v4.21.0/log/logger.go:48 > [INFO] [dozzle.r****h.com] acme: Waiting for DNS record propagation. lib=lego

And in DigitalOcean I can see that TXT records are created:

But after a minute or so the following error messages appear in my logs:

ERR github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:482 > Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [dozzle.r****h.com]: error: one or more domains had a problem:\n[dozzle.r****h.com] propagation: time limit exceeded: last error: [zone=r***h.com.] could not determine authoritative nameservers\n" ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory domains=["dozzle.r***h.com"] providerName=letsencrypt.acme routerName=dozzle@docker rule=Host(dozzle.r****h.com)

My labels for individual services are pretty simple (I'll post a full docker-compose.yml below as well):

      - traefik.enable=true
      - traefik.http.routers.dozzle.rule=Host(`dozzle.r***h.com`)

Traefik itself is configured with a yaml file, the cert resolver bit looks like this (I'll again attach the full config file below):

entryPoints:
  websecure:
    address: :443
    forwardedHeaders:
      insecure: true
    http:
      tls:
        certresolver: letsencrypt
        domains:
          - main: "r***h.com"
            sans:
              - "*.r***h.com"

certificatesResolvers:
  letsencrypt:
    acme:
      email: email@email.com
      storage: "/acme/acme.json"
      dnsChallenge:
        provider: digitalocean
        delayBeforeCheck: 0
        resolvers:
          - "ns1.digitalocean.com:53"
          - "ns2.digitalocean.com:53"
          - "ns3.digitalocean.com:53"
        propagation:
          delayBeforeChecks: 15s

And when I run dig inside the Traefik container while it's attempting to start up (and the records show as created in DigitalOcean) but it doesn't appear to resolve correctly, however I may also be querying the DNS records incorrectly.

Optimally Traefik will request and use a single certificate for all the wildcard domains on my network. If anyone can see what I'm doing wrong I really appreciate any guidance!! Thank you!

Traefik docker-compose
version: "3"
services:
  traefik:
    image: traefik:latest
    container_name: traefik
    env_file: /opt/stacks/traefik/.env
    restart: always
    ports:
      # The HTTP port
      - 80:80
      - 443:443
      - 8080:8080
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
      - /opt/stacks/traefik/traefik.yml:/traefik.yml
      - /opt/stacks/traefik/traefik-dynamic.yml:/traefik-dynamic.yml
      - /opt/stacks/traefik/acme:/acme
    labels:
      - traefik.enable=true
      - traefik.http.routers.proxy.rule=Host(`traefik.r***h.com`)
      - traefik.http.routers.proxy.service=api@internal
    networks:
      - proxy
networks:
  proxy:
    external: true
Service docker-compose
services:
  dozzle:
    container_name: dozzle
    image: amir20/dozzle:latest
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - proxy
    labels:
      - traefik.enable=true
      - traefik.http.routers.dozzle.rule=Host(`dozzle.r***h.com`)
networks:
  proxy:
    external: true
Traefik.yml static config
log:
  level: DEBUG

accesslog: true

api:
  dashboard: true
  insecure: false

entryPoints:
  web:
    address: :80
    forwardedHeaders:
      insecure: true
    http:
      redirections:
        entrypoint:
          to: websecure
          scheme: https

  websecure:
    address: :443
    forwardedHeaders:
      insecure: true
    http:
      tls:
        certresolver: letsencrypt
        domains:
          - main: "r***h.com"
            sans:
              - "*.r***h.com"

  other:
    address: ":9090/udp"


certificatesResolvers:
  letsencrypt:
    acme:
      email: email@email.com
      storage: "/acme/acme.json"
      dnsChallenge:
        provider: digitalocean
        delayBeforeCheck: 0
        resolvers:
          - "ns1.digitalocean.com:53"
          - "ns2.digitalocean.com:53"
          - "ns3.digitalocean.com:53"
        propagation:
          delayBeforeChecks: 15s

providers:
  docker:
    watch: true
    network: proxy
    exposedByDefault: false

  file:
    filename: "/traefik-dynamic.yml"
Traefik-dynamic.yml dynamic config
http:
  middlewares:
    simpleAuth:
      basicAuth:
        users:
          - "admin:hashvalue"

Did you test without delayBeforeCheck, delayBeforeChecks? It seems some defaults are using longer timeout (doc).

Did you test without resolvers? I would expect default to work here, too.

Did you try to set environment variable LEGO_DISABLE_CNAME_SUPPORT=true (doc)?

Yes I tried without the delayBeforeCheck value and commenting out the resolvers, same issue. I tried adding the LEGO_DISABLE_CNAME_SUPPORT=true variable, but same exact behavior.

Additionally here's the JSON config (I removed all but one service to keep it clean, but all the other services have the same definitions)

JSON config
{
    "http": {
        "middlewares": {
            "cors": {
                "headers": {
                    "accessControlAllowCredentials": true,
                    "accessControlAllowHeaders": [
                        "Authorization",
                        "Content-Type"
                    ],
                    "accessControlAllowMethods": [
                        "*"
                    ],
                    "accessControlAllowOriginList": [
                        "*"
                    ],
                    "accessControlMaxAge": 100,
                    "addVaryHeader": true
                }
            }
        },
        "routers": {
            "dozzle": {
                "entryPoints": [
                    "websecure"
                ],
                "rule": "Host(`dozzle.r***h.com`)",
                "service": "dozzle-dozzle",
                "tls": {
                    "certResolver": "letsencrypt"
                }
            }
        },
        "services": {
            "dozzle-dozzle": {
                "loadBalancer": {
                    "passHostHeader": true,
                    "responseForwarding": {
                        "flushInterval": "100ms"
                    },
                    "servers": [
                        {
                            "url": "http://10.89.11.57:8080";
                        }
                    ]
                }
            }
        }
    },
    "tcp": {},
    "tls": {},
    "udp": {}
}

The best way to debug is probably to use the go-acme tool and try to generate the certs on command line, it's the library that Traefik uses internally. There currently seems to be no issue with digitalocean.

Hmm, no luck there, same behavior using the lego CLI tool directly, here's the output:

lego output
/ # DO_AUTH_TOKEN=auth_token_hidden lego --email email@email.com --dns digitalocean --dns.resolvers ns1.digitalocean.com -d '*.r***h.com' 
-d r***h.com run
2025/01/22 16:20:33 [INFO] [*.r***h.com, r***h.com] acme: Obtaining bundled SAN certificate
2025/01/22 16:20:34 [INFO] [*.r***h.com] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz/2185194195/464589711925
2025/01/22 16:20:34 [INFO] [r***h.com] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz/2185194195/464589711935
2025/01/22 16:20:34 [INFO] [*.r***h.com] acme: use dns-01 solver
2025/01/22 16:20:34 [INFO] [r***h.com] acme: Could not find solver for: tls-alpn-01
2025/01/22 16:20:34 [INFO] [r***h.com] acme: Could not find solver for: http-01
2025/01/22 16:20:34 [INFO] [r***h.com] acme: use dns-01 solver
2025/01/22 16:20:34 [INFO] [*.r***h.com] acme: Preparing to solve DNS-01
2025/01/22 16:20:34 [INFO] Found CNAME entry for "_acme-challenge.r***h.com.": "r***h.com."
2025/01/22 16:20:35 [INFO] [r***h.com] acme: Preparing to solve DNS-01
2025/01/22 16:20:35 [INFO] Found CNAME entry for "_acme-challenge.r***h.com.": "r***h.com."
2025/01/22 16:20:35 [INFO] [*.r***h.com] acme: Trying to solve DNS-01
2025/01/22 16:20:35 [INFO] Found CNAME entry for "_acme-challenge.r***h.com.": "r***h.com."
2025/01/22 16:20:35 [INFO] [*.r***h.com] acme: Checking DNS record propagation. [nameservers=ns1.digitalocean.com:53]
2025/01/22 16:20:40 [INFO] Wait for propagation [timeout: 1m0s, interval: 5s]
2025/01/22 16:20:40 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:20:45 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:20:50 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:20:55 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:00 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:05 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:10 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:16 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:21 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:26 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:31 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:36 [INFO] [*.r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:41 [INFO] [r***h.com] acme: Trying to solve DNS-01
2025/01/22 16:21:41 [INFO] Found CNAME entry for "_acme-challenge.r***h.com.": "r***h.com."
2025/01/22 16:21:41 [INFO] [r***h.com] acme: Checking DNS record propagation. [nameservers=ns1.digitalocean.com:53]
2025/01/22 16:21:46 [INFO] Wait for propagation [timeout: 1m0s, interval: 5s]
2025/01/22 16:21:46 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:51 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:21:56 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:01 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:06 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:11 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:17 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:22 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:27 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:32 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:37 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:42 [INFO] [r***h.com] acme: Waiting for DNS record propagation.
2025/01/22 16:22:47 [INFO] [*.r***h.com] acme: Cleaning DNS-01 challenge
2025/01/22 16:22:47 [INFO] Found CNAME entry for "_acme-challenge.r***h.com.": "r***h.com."
2025/01/22 16:22:47 [INFO] [r***h.com] acme: Cleaning DNS-01 challenge
2025/01/22 16:22:47 [INFO] Found CNAME entry for "_acme-challenge.r***h.com.": "r***h.com."
2025/01/22 16:22:48 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz/2185194195/464589711925
2025/01/22 16:22:48 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz/2185194195/464589711935
2025/01/22 16:22:48 Could not obtain certificates:
        error: one or more domains had a problem:
[*.r***h.com] propagation: time limit exceeded: last error: [zone=r***h.com.] could not determine authoritative nameservers
[r***h.com] propagation: time limit exceeded: last error: [zone=r***h.com.] could not determine authoritative nameservers

And similarly it running from Traefik automatically I can see the TXT records getting created in DigitalOcean while this is running:

But still the same timeout issue occurs. I did try to hop over to another CLI and test with dig to see if I could see the actual DNS records showing up or not, not sure if I'm using it/querying correctly but no results show up:

And just to retrace my steps, I hopped into the actual Traefik container and installed the lego cli tool, and ran with this command:

DO_AUTH_TOKEN=auth_token lego --email email@email.com --dns digitalocean --dns.resolvers ns1.digitalocean.com -d '*.r***h.com' -d r***h.com run

I tried without the --dns.resolvers flag but noted it was hitting my local PiHole DNS servers, and added it to test, but hit the same behaviors on both tests.

I wonder if this is related to my actual DNS setup of my domain, to sanity check some things I went to this site to pull DNS records: https://dnschecker.org

However, when trying to pull records it throws the same (rough) error that it's unable to determine the "Authoritative NS"

image

And just for reference the error lego returns (and that I see in Traefik logs):

[*.r***h.com] propagation: time limit exceeded: last error: [zone=r***h.com.] could not determine authoritative nameservers

The domain is registered with Namecheap, and it has some NS records:

Then on DigitalOcean the DNS settings are pretty simple, outside of my A and CNAME records for the IP of my server itself and the wildcard subdomain and some MX records nothing else is in there.

Are my DNS settings incorrect? Perhaps I need to add NS records to DigitalOcean? But wouldn't they just point back to ns1/2/3.digitalocean.com?

Apologies my knowledge on DNS settings are limited, I really appreciate the help and advice!

Your domain is with Namecheap, but you set DNS with DigitalOcean?

So first of all, SUCCESS! I added NS records for ns1/ns2/ns3.digitalocean.com to my DNS records in Digitalocean, and after a min to propagate the calls to create the certificates succeeded!!! The entire issue all along was the weird DNS setup I have for the domains

And to answer your question, yeah, I'm not the biggest fan of it being split up between Namecheap and DigitalOcean, if I recall correctly I can't use Namecheap because they restrict API access unless you have a certain number of domains or pay extra, and I don't want to lol.

To anyone who finds this issue via Google in the future, make sure you're getting back NS records when looking up the DNS records for your domain, that appears to have been my issue all along!

1 Like