[Dnsmasq-discuss] [PATCH] Don't penalize conditional forwarders for REFUSED responses
Dominik Derigs
dl6er at dl6er.de
Mon Apr 6 08:45:03 UTC 2026
Hi Simon,
When a conditional forwarder (server=/domain/addr) points at an
authoritative-only nameserver that doesn't support recursion, three
things go wrong over time:
- process_reply() warns "nameserver X refused to do a recursive
query" on every response that lacks the RA bit. For an authoritative
server this is expected, not an error.
- reply_query() clears last_server on REFUSED, which forces the next
query into forwardall mode. That query sets last_server again on
success, so the one after that runs with forwardall == 0 re-entering the
code path where REFUSED triggers the retry and penalty. The clearing
sustains this cycle.
- reply_query() retries REFUSED through forward_query(), which bumps
failed_queries and tries other servers in the group. With only one
server for the domain the retry just re-sends to the same place; if that
fails again, the response eventually falls through to general upstreams
which return NXDOMAIN for the local domain.
The cumulative effect is that local-domain resolution degrades until
dnsmasq is restarted. This is a common setup with Active Directory DNS
or other authoritative-only forwarders behind conditional forwarding rules.
The attached patch adds a server->domain_len == 0 guard to all three
code paths so the existing REFUSED/RA-bit handling continues to apply to
general upstream servers but is skipped for domain-specific ones.
SERVFAIL still triggers retries for all servers as before, since that
indicates a genuine server error rather than an expected policy response.
Typical configuration that triggers the problem:
server=/localdomain.ca/192.168.0.2 # AD DNS, authoritative only
server=10.0.0.1 # Unbound, recursive
The AD DNS answers localdomain.ca queries without RA, and returns
REFUSED for anything outside its zone. Without the patch, the REFUSED
handling progressively penalizes 192.168.0.2 until localdomain.ca
queries start going to Unbound which returns NXDOMAIN.
This has first been reported at
https://github.com/pi-hole/FTL/issues/2836 but is something that needs
to be fixed in dnsmasq itself, so I'm submitting the patch here.
Cheers,
Dominik
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Don-t-penalise-conditional-forwarders-for-REFUSED-re.patch
Type: text/x-patch
Size: 4454 bytes
Desc: not available
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20260406/f84ffd2b/attachment.bin>
More information about the Dnsmasq-discuss
mailing list