Migrate to new Hetzner-Cloud-DNS Certificates via DNS-API for Homeassistant running on a private hostname

All Logos rights lie at their respective owners.

Because this problem cost me some time, I am sure someone else can get some value out of this. The old Hetzner-DNS-API is beeing phased out right now, so it’s time to hurry up…

Given be the following setup:

  • You are using Hetzner for your domain, and are still on the old API (dns-hetzner as provider for the letsencrypt_core Homeassistant addon)
  • You actually fetch LE-certs via DNS-API, and not via webroot or similar
  • The hostname Homeassistant is using, is not publicly known (nor publicly rechable), and the public zonefile does not list an A/AAAA/CNAME record for that hostname (instead it is only reachable locally or via VPN, and is resolved by an internal DNS)

…then maybe you have run into Problems when trying to migrate to the new Hetzner DNS-API. Anyway, here’s how to solve this problem.

While the migration went somewhat smooth for me, migrating Homeassistant specifically gave me some true headache. But first let some technical details sink in for better understanding.

The old DNS-API of Hetzner (a large german VPS and domain provider) was/is listed as separate module within the letsencrypt-homeassistant-addon. While most appliances capable of fetching certificates by using ACME (like for Let’s Encrypt certs) already implemented a new provider-module for the new API (hetzner-dns-cloud, hetzner-cloud or similar), the Homeassistant-Addon did not (yet?) implemented those. So for let’s say „Nginx-Proxy-Manager“ or „pfSense“ everything is fine. As long as your acme/lets-encrypt-plugin is reasonably recent, everything is smooth sailing.

For everything that uses „lego“ (an acme-implementation written in go) as acme-fetcher, this is a little different. Because lego has not yet implemented dns-hetzner-cloud as standalone-provider, you have to pass the dns-provider by an environment-variable to lego, which then acts as a generic wrapper for that provider. This applies to said homeassistant-plugin, traekif (AFAIK) and of course lego itself (beside others). The core-problem is that lego tries to get authorative requests (SOA) for the hostname it is trying to fetch certificates for. Homelab-setups most likely won’t be able to statisfy this requirement, because the domain-zonefile does not know that hostname (if it is not publicly known), and the local DNS does know the hostname, but cannot answer authoratively. The result is, that you see something like unexpected response for the SOA-Section resulting in a SERVFAIL or FORBIDDEN as answer, depending on the configuration. In my case it looked like this (docker log from the letsencrypt_core-plugin in Homeassistant):

Instead of figuring out, how to cascade the local DNS so that it can answer authoratively for your domain, the easiest way is to use public DNS-Servers only for fetching the certificate and the authorative part. However, your homeassistant itself should keep using the local DNS, because otherwise it cannot resolve the hostnames of all the small devices it talks to. Lego luckily has options for specificly that. You however have to make sure, that homeassistant can reach public DNS servers (in my homelab I usually block public DNSses and DoT-Traffic for clients, and instead force them to use pi-hole, so that they cannot violate my DNS-settings to fetch Ads anyways).

If HA can reach public DNSses (I use Googles primary public DNS Server 8.8.8.8 and quad-one 1.1.1.1 as example here), for the first fetch you should enforce renewing and set the propagation time to 120 to let things settle. The Lets-Encrypt-Plugin-configuration should then look like this:

Note that this is the yaml-config and that yaml is sensitive to indentation and placement of dashes. the configuration must adhere to yaml standards. Homeassistant might automatically include an extra-line like „>-“ above the api-token. This is fine.

With that config I was finally able to fetch certificates with the new DNS-API. Hope you have had some success too, before the old API is going down (which will be in may of 2026)…

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert