Show full content
Recently, I found in the Postfix logs on my personal mail server some suspicious temporary rejects,
with error
Client host rejected: cannot find your reverse hostname [212.132.99.84]
The email was eventually delivered after several retries. The root cause needs investigation.
The initial assumption was that Postfix was misconfigured. Reproduced the issue locally for further analysis.
# nslookup 212.132.99.84
;; Got SERVFAIL reply from ::1, trying next server
;; Got SERVFAIL reply from 127.0.0.1
** server can't find 84.99.132.212.in-addr.arpa: SERVFAIL
On the second or third try, the call was usually successful. I was also able to reliably reproduce the issue by running rndc flush && 212.132.99.84.
First guess was that something was very wrong with DNS servers for the 84.99.132.212.in-addr.arpa. However, I did not spot any significant issues with dnsviz.net or dig +trace. The host’s recursive DNS resolver is BIND9 with some configuration changes.
So I decided to reproduce the issue locally by installing BIND 9.20 in a VM with a default configuration. The issue is easily reproducible:
# rndc flush && dig -x 212.132.99.84 @127.0.0.1
; <<>> DiG 9.20.22 <<>> -x 212.132.99.84 @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 62425
Looking at tcpdump, I see many queries to root DNS servers. This is an example of the dump:
192.58.128.30.53 > 192.168.64.2.55622: 23480*- 2/13/3 e.ns.arpa. A 192.203.230.10, e.ns.arpa. RRSIG (1136)
08:50:59.176320 IP (tos 0x0, ttl 54, id 18377, offset 0, flags [none], proto UDP (17), length 1164)
192.58.128.30.53 > 192.168.64.2.52994: 21314*- 2/13/3 h.ns.arpa. A 198.97.190.53, h.ns.arpa. RRSIG (1136)
08:50:59.176326 IP (tos 0x0, ttl 54, id 18378, offset 0, flags [none], proto UDP (17), length 1176)
192.58.128.30.53 > 192.168.64.2.62054: 35468*- 2/13/3 g.ns.arpa. AAAA 2001:500:12::d0d, g.ns.arpa. RRSIG (1148)
08:50:59.176333 IP (tos 0x0, ttl 54, id 18379, offset 0, flags [none], proto UDP (17), length 1164)
192.58.128.30.53 > 192.168.64.2.54688: 16143*- 2/13/3 g.ns.arpa. A 192.112.36.4, g.ns.arpa. RRSIG (1136)
08:50:59.176342 IP (tos 0x0, ttl 54, id 18381, offset 0, flags [none], proto UDP (17), length 1176)
192.58.128.30.53 > 192.168.64.2.52248: 2148*- 2/13/3 e.ns.arpa. AAAA 2001:500:a8::e, e.ns.arpa. RRSIG (1148)
08:50:59.176353 IP (tos 0x0, ttl 54, id 18380, offset 0, flags [none], proto UDP (17), length 1176)
192.58.128.30.53 > 192.168.64.2.64187: 49690*- 2/13/3 h.ns.arpa. AAAA 2001:500:1::53, h.ns.arpa. RRSIG (1148)
But surprisingly, there are no failed or successful requests to the rns.ui-dns.biz/rns.ui-dns.com/rns.ui-dns.org/rns.ui-dns.de which are authoritative servers for that record. The resolver never proceeds to the final query.
So let’s go debugging by adding logs:
logging {
channel query_log {
file "/var/log/named/query.log" versions 3 size 10m;
severity debug 3;
print-time yes;
print-severity yes;
print-category yes;
};
category queries { query_log; };
category resolver { query_log; };
category dnssec { query_log; };
};
This actually helps to find a root cause:
28-Apr-2026 08:59:17.655 resolver: debug 3: exceeded max queries resolving 'd.in-addr-servers.arpa/AAAA' (max-recursion-queries, querycount=50)
28-Apr-2026 08:59:17.655 resolver: debug 3: exceeded max queries resolving 'e.in-addr-servers.arpa/A' (max-recursion-queries, querycount=51)
28-Apr-2026 08:59:17.656 resolver: debug 3: exceeded max queries resolving 'e.in-addr-servers.arpa/AAAA' (max-recursion-queries, querycount=51, maxqueries=50)
28-Apr-2026 08:59:17.656 resolver: debug 3: exceeded max queries resolving 'f.in-addr-servers.arpa/A' (max-recursion-queries, querycount=51, maxqueries=50)
28-Apr-2026 08:59:17.656 resolver: debug 3: exceeded max queries resolving 'f.in-addr-servers.arpa/AAAA' (max-recursion-queries, querycount=51, maxqueries=50)
28-Apr-2026 08:59:17.656 resolver: debug 3: exceeded max queries resolving 'd.in-addr-servers.arpa/A' (max-recursion-queries, querycount=51, maxqueries=50)
28-Apr-2026 08:59:17.656 resolver: debug 3: exceeded max queries resolving '84.99.132.212.in-addr.arpa/PTR' (max-recursion-queries, querycount=51, maxqueries=50)
Changing configuration
BIND recently added query limits to avoid DDoS attacks.
It introduces a new option max-recursion-queries with default to 50. Let’s change it to 500 to see if that helps.
Test still returns SERVFAIL, but the log now shows a different error:
28-Apr-2026 09:09:57.084 dnssec: debug 3: validating 132.212.in-addr.arpa/NS: resuming validate_nx
28-Apr-2026 09:09:57.084 resolver: debug 3: exceeded global max queries resolving '84.99.132.212.in-addr.arpa/PTR' (max-query-count, querycount=201, maxqueries=200)
One more limit, this time maxqueries. It is controlled by the max-query-count option (default: 200). Once I set it to 500, BIND finally resolved the PTR record. This also explains why resolution eventually succeeds – BIND caches successful calls and will eventually be able to resolve the target record without hitting the limit.
BIND debug logs show that we are fetching 483 records for the very simple DNS PTR query. Contributing factors are IPv6 (A/AAAA duplications), DNSSEC (DS/DNSKEY), and queries to the root DNS servers.
BIND now supports mirroring of the root zone, so let’s try to enable it by replacing
zone "." {
type hint;
file "/usr/local/etc/namedb/named.root";
};
With
zone "." {
type mirror;
};
After the restart, I repeated my test, and the number of fetches reduced from 483 to 99. This should also significantly reduce DNS resolution time/
ConclusionFrom my POV, something is very wrong with the default BIND configuration and DNS protocol in general. By adding more and more functions, we now need hundreds of calls to do a very basic lookup. Root zone caching, as well as query limit fine-tuning, may fix (or hide) the issue, but the overall complexity of the DNS is not something I would expect to see. Also, errors like this are likely to go unnoticed in many systems, reducing Internet/DNS reliability and performance.












