DuckDNS aliases not working?

Hi everyone, I recently set up a new Home Assistant instance on a rpi 3b+ (currently v.0.110.0), and I have remote access with SSL working using the DuckDNS add-on. I’m trying to set it up to work with my personal domain using the add-on’s “aliases” option. I have a CNAME set up from my personal domain to my DuckDNS domain. My config is as follows:

lets_encrypt:
  accept_terms: true
  certfile: fullchain.pem
  keyfile: privkey.pem
token: MY_TOKEN
domains:
  - MY_DUCKDNS_DOMAIN.duckdns.org
  - MY_DOMAIN
aliases:
  - domain: MY_DOMAIM
    alias: MY_DUCKDNS_DOMAIN.duckdns.org
seconds: 300

I can access remotely with SSL using the MY_DUCKDNS_DOMAIN.duckdns.org, but when I access using MY_DOMAIN, it connects without SSL.

Are aliases not working, or have I do e something wrong?

Polite bump. Surely this isn’t a new problem, but despite my hours of Googling, still no luck.

If you have your own domain, use letsdnsocloud.

Thanks francisp, I’ll check that out!

Same issue here. For one of my HA installs it worked great (after figuring out the correct CNAME records thanks to this comment ), but for another, the certificate does not become valid for the domain that is set as an alias.

When inspecting the certificate it seems that the ‘Subject Alternative Name’ is not set correctly. Is there a cache that should be removed? Simply reinstalling DuckDNS, or re-adding the domain to DuckDNS does not resolve the issue.

For everyone still searching for the solution to this problem. I wrote a detailled guide to the solution:

2 Likes

Hi all, 3 months down the road with HA, still considering myself pretty new to HA. I’m running into what seems is a common issue with the DuckDNS/LetsEncrypt supervisor addon.

TLDR; I’m trying to set up my own with LetsEnrypt certificate. DuckDNS domain cert is generated fine, yet getting the ERROR: Challenge is invalid! full details below) when I try to add my own domain to the configuration

Commentary: It seems there’s something missing from the otherwise helpful guides out there as the letsencrypt API generates a token, which it is looking for as a TXT dns record? The part I’m missing is how does that DNS entry get there? I mean I could add it manually, but as the token changes every time the cert request begins, it’s a moot point. I read something about ACME protocol, which I’m presuming might be what I’m missing, yet it seems my domain registrar/dns provider MyDomain does not support that? Is that the issue I’m having?

Second, I’m reading here and there that I need to open port 80 or 443 temporarily in my router at least temporarily. Port 80 is a no-go as Cox filters that port out, but I can do 443. What is the purpose of this?

This is my duckdns configuration:

lets_encrypt:
 accept_terms: true
 certfile: fullchain.pem
 keyfile: privkey.pem
token: tokentokentokentoken
domains:
 - myname.duckdns.org
aliases:
 - domain: ha.myowndomain.com
   alias: myname.duckdns.org
seconds: 300

When I start up dockdns, this is what the log looks like.

[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] done.
[services.d] starting services
[services.d] done.
# INFO: Using main config file /data/workdir/config
+ Generating account key...
+ Registering account key with ACME server...
+ Fetching account ID...
+ Done!
[09:39:32] INFO: OK
my.ext.ip.addr
NOCHANGE
[09:39:32] INFO: Renew certificate for domains: myname.duckdns.org and aliases: 
ha.myowndomain.com
# INFO: Using main config file /data/workdir/config
 + Creating chain cache directory /data/workdir/chains
Processing myname.duckdns.org with alternative names: ha.myowndomain.com
 + Creating new directory /data/letsencrypt/mynameduckdns.org ...
 + Signing domains...
 + Generating private key...
 + Generating signing request...
 + Requesting new certificate order from CA...
 + Received 2 authorizations URLs from the CA
 + Handling authorization for myname.duckdns.org
 + Handling authorization for ha.myowndomain.com
 + 2 pending challenge(s)
 + Deploying challenge tokens...
OKOK + Responding to challenge for myname.duckdns.org authorization...
 + Cleaning challenge tokens...
OKOK + Challenge validation has failed :(
ERROR: Challenge is invalid! (returned: invalid) (result: {
  "type": "dns-01",
  "status": "invalid",
  "error": {
    "type": "urn:ietf:params:acme:error:unauthorized",
    "detail": "Incorrect TXT record \"sometokenplaceholder\" found at _acme-challenge.myname.duckdns.org",
    "status": 403
  },
  "url": "https://acme-v02.api.letsencrypt.org/acme/chall-v3/somenumber/someothernumber",
  "token": "anothertokenplaceholder"
})

If anyone can offer advice as to what I need to change it would be hugely appreciated. Do I need to make manual changes on my domain? (I’ve already got a CNAME record for *.myowndomain.com pointing to myname.duckdns.org. I’ve opened TCP/443 and portforwarded it to my HA box. thank you!

1 Like

Debugged this issue today

Setup:

  • DuckDNS Addon configured with:
    • A primary DuckDNS domain (e.g., <your_subdomain>.duckdns.org)
    • A custom alias domain pointing to the DuckDNS domain (e.g., <your_alias.yourdomain.com>)
  • DNS Configuration: A CNAME record was set up for _acme-challenge.<your_alias.yourdomain.com> pointing to _acme-challenge.<your_subdomain>.duckdns.org. This delegates the ACME DNS-01 challenge validation for the alias domain to the DuckDNS domain.

The Problem:

Certificate renewals would fail consistently. The DuckDNS addon log showed errors similar to:
ERROR: Challenge is invalid! (returned: invalid) … “Incorrect TXT record “…” found at _acme-challenge.<your_alias.yourdomain.com>”

The Root Cause:

The actual issue arises from how ACME challenges work with multiple domains and CNAME delegation in this specific scenario:

  • The ACME client (dehydrated used by the addon) requests validation for both <your_subdomain>.duckdns.org and <your_alias.yourdomain.com>.
  • Let’s Encrypt issues separate challenges, requiring different unique TXT token values for each domain.
  • Because of the CNAME, the validation for both domains requires setting a TXT record on the same DNS name: _acme-challenge.<your_subdomain>.duckdns.org.
  • The hooks.sh script gets called sequentially for each challenge. It successfully sets the TXT record for the first domain, but then immediately gets called for the second domain and overwrites the first TXT record with the second token value.
  • Since the DuckDNS API only allows one TXT record value at a time, when Let’s Encrypt checks, one of the required tokens is always missing, causing validation failure.

Modifying the addon’s hooks.sh to handle this complex interaction won’t work as challenges are verified one after another without any hooks being invoked.

Changing the run script to invoke dehydrated for domain and alias separately won’t work either: produced certificate needs to list both hence we have to pass both to the same command.

So we need to change dehydrated script to either set/verify challenges one by one or to reuse the same challenge for both domains. WDYT?

The lack of waiting is also an issue. I propose to use dig to periodically check the TXT value and then return:

curl -s "https://www.duckdns.org/update?domains=$ALIAS&token=$SYS_TOKEN&txt=$TOKEN_VALUE"
timeout 60s bash -c -- "while ! dig -t txt _acme-challenge.$ALIAS | grep $TOKEN_VALUE > /dev/null; do sleep 1; done"

Created Wait for TXT record to propagate by rryk · Pull Request #3979 · home-assistant/addons · GitHub.