Jeffrey Harris

Acme Challenge and Wildcards

My Traefik server hasn't been able to update the TLS certificate on one of my domains. Everything looks like it should work, but it doesn't, and it's a bit frustrating to work through.

I've been running my own authoritative DNS for years now. It started with wanting SSHFP records so I could verify I was actually connecting to my server from a hotel Wi-Fi at Disneyland (long story, involves a young child and unexpected weekend trips). These days I have four BIND9 servers scattered across different providers — the only thing that can take them all down is if my billing doesn't go through.

When I hooked up Traefik to handle automatic TLS via Let's Encrypt, I originally just used a certificate for a specific domain name, and that was simple enough. But over time, those subdomains add up. So I switched to wildcard domains.

For a wildcard cert, Let's Encrypt requires a DNS-01 challenge: it asks you to place a temporary TXT record at _acme-challenge.yourdomain.com, then checks that it's there. If the record matches what they asked for, you're authorized. Since I have my own Bind 9 servers, I use the RFC2136 provider with a TSIG key to talk between my Traefik box and my primary DNS server. This works great for regular domains. But there's a catch: if your zone already has a wildcard subdomain (*.example.com), the lego client can't create the _acme-challenge subdomain and add the TXT record. The wildcard matches everything, including _acme-challenge, so the DNS server refuses the update — you're trying to add a record under a name that already "exists" via the wildcard.

Traefik's error message isn't exactly helpful:

ERR Error renewing ACME certificate: {1x0.us [*.1x0.us]} error="resolver: one or more domains had a problem: [*.1x0.us:
dns01: error presenting token (*.1x0.us): dnsupdate: failed to insert: DNS update failed: server 161.35.253.21:53 replied
REFUSED for INSERT myhostingaccount.info.] [1x0.us: dns01: error presenting token (1x0.us): dnsupdate: failed to insert:
DNS update failed: server 161.35.253.21:53 replied REFUSED for INSERT myhostingaccount.info.]"
acmeCA=https://acme-v02.api.letsencrypt.org/directory providerName=dns-lets-encrypt.acme

Part of the problem with the message is that it mentions two domains. One is the domain that it's trying to update, and one is the domain of the DNS server. Without the subdomain.

That REFUSED for INSERT is the key. The DNS server is saying "no, you can't add a record there because the wildcard already owns that space."

The solution is to explicitly create the _acme-challenge subdomain before Traefik tries to use it. Since the TXT record on _acme-challenge is ephemeral (Let's Encrypt creates and removes it for each challenge), we don't want a structural record that might interfere. The cleanest record type for this is RP — Responsible Person. It's formatted like the RNAME field in an SOA record: an email address with the @ replaced by a dot.

First, check your SOA to see what the responsible person address looks like:

$ dig soa jeffharris.us +short
ns2.myhostingaccount.info. ptr.myhostingaccount.info. 2026051394 604800 7200 2419200 10800

The second field (ptr.myhostingaccount.info.) is the RNAME — the email address of the zone administrator, with @ turned into a dot. So the responsible person is ptr@myhostingaccount.info.

Now add an RP record for _acme-challenge using that same address:

; jeffharris.us/zone
$TTL 86400 ; 1 day
_acme-challenge.jeffharris.us. RP ptr.myhostingaccount.info. .

That trailing dot after the RP target is important — it's the "root" of the DNS name, effectively making this ptr.myhostingaccount.info. a fully qualified domain name. The final . in the record is the TXT-DATA field for RP ( which can be empty or point to a TXT record with more contact info; we leave it empty).

Add that line to your zone file (or your dynamic zone if you're using nsupdate), reload BIND, and Traefik can now create its temporary TXT records under _acme-challenge without the wildcard getting in the way.

I put this on every domain that has a wildcard subdomain now — just another piece of boilerplate alongside the NS records and the usual infrastructure. Once it's there, the wildcard cert renewals just work.


This is one of those things that's obvious in retrospect but maddening in the moment. If you're running your own BIND with wildcard subdomains and RFC2136 DNS updates for ACME, save yourself the headache: pre-create _acme-challenge with an RP record pointing to your SOA RNAME.