Skip to main content
Ubuntu, Debian, Fedora and many other distributions run systemd-resolved, which already listens on 127.0.0.53:53. DNZ then can’t bind 0.0.0.0:53:
See what’s using the port:
1

Turn off systemd-resolved's stub listener

2

Repoint /etc/resolv.conf

/etc/resolv.conf usually points at the 127.0.0.53 stub, which no longer exists. Point it at systemd-resolved’s real DNS list, so this server can still resolve names itself (apt update, curl and so on):
Skip this and the rest of the server (apt, curl and so on) can no longer resolve any name once the stub is off. DNZ itself keeps working: see DNZ’s own lookups.
3

Restart systemd-resolved, then DNZ

4

Check

DNZ’s own lookups

DNZ’s own connections (Cloudflare, ACME, S3 backups, webhooks, block lists, the release check) don’t depend on /etc/resolv.conf. When the system resolver fails, DNZ looks the name up through its own DNS server on loopback, then through public resolvers (1.1.1.1, 8.8.8.8, 9.9.9.9). Connecting Cloudflare works even while /etc/resolv.conf still points at the dead stub.

Use DNZ as this server’s resolver

Writing nameserver 127.0.0.1 into /etc/resolv.conf by hand doesn’t last: systemd-resolved, NetworkManager, netplan or DHCP rewrite the file. Tell systemd-resolved instead, and keep /etc/resolv.conf linked to the file it maintains:
127.0.0.1 comes first and the DNS servers from DHCP stay behind it, so the machine still resolves names while DNZ is stopped.
If you use encrypted upstreams by name, add #ip to them to avoid a loop; see upstream addresses.

Option 2: bind DNZ to one address

Leave systemd-resolved alone and listen only on the server’s LAN address:
/etc/dnz/dnz.env
With Docker, publish the port on that address instead:

Other programs on port 53

dnsmasq, bind9, unbound and pihole-FTL use port 53 too. Stop that program, for example sudo systemctl disable --now dnsmasq, or bind DNZ to another address.