[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