Repository navigation
Resolving NS records against manual configured servers fails (ENODATA) #33858
Description
- Version: v14.4.0
- Platform: Linux wolfgang-ThinkPad-P51 5.4.0-31-generic net: give better error messages #35-Ubuntu SMP Thu May 7 20:20:34 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
- Subsystem: dns
What steps will reproduce the bug?
First, you need a DNS zone with NS records delegating a subdomain to another DNS zone.
I set up an example on our domain:
root domain: ventx.de
delegated subdomain: delegation-test.ventx.de
The zone ventx.de contains a NS record "delegation-test.ventx.de" with this content:
ns-1926.awsdns-48.co.uk.
ns-670.awsdns-19.net.
ns-282.awsdns-35.com.
ns-1527.awsdns-62.org.
This can be tested with dig delegation-test.ventx.de NS @ns-675.awsdns-20.net, which results in the very same output, so the zone is setup correctly.
For the following description I'll use the IP address of ns-675.awsdns-20.net, which is 205.251.194.163
When you try to replicate this query with nodejs, an ENODATA error is thrown:
Error: queryNs ENODATA delegation-test.ventx.de
at QueryReqWrap.onresolve [as oncomplete] (dns.js:203:19) {
errno: undefined,
code: 'ENODATA',
syscall: 'queryNs',
hostname: 'delegation-test.ventx.de'
} undefined
This is the output of the following code-snippet:
const {Resolver} = require('dns');
const resolver = new Resolver();
resolver.setServers(['205.251.194.163']);
resolver.resolve('delegation-test.ventx.de', 'NS', (err, resolve) => {
console.log(err, resolve);
});I debugged this also with wireshark and was able to see, that the actual query to the nameserver
is correct and also the response is coming back with the correct recordSet:

As you can see, the response has the status "No error", however nodejs throws an ENODATA error.
How often does it reproduce? Is there a required condition?
I was able to reproduce the bug everytime without any other condition
What is the expected behavior?
null [
'ns-670.awsdns-19.net',
'ns-282.awsdns-35.com',
'ns-1926.awsdns-48.co.uk',
'ns-1527.awsdns-62.org'
]
that's how the output of the snippet looks like, when you to not manually set a server
What do you see instead?
Error: queryNs ENODATA delegation-test.ventx.de
at QueryReqWrap.onresolve [as oncomplete] (dns.js:203:19) {
errno: undefined,
code: 'ENODATA',
syscall: 'queryNs',
hostname: 'delegation-test.ventx.de'
} undefined
Additional information
I was also able to reproduce the issue with the node:latest docker container:
$ node -v
v14.4.0
$ uname -a
Linux runner-6ab0c1ba-project-16-concurrent-0 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 GNU/Linux
$ node dns_fail.js
Error: queryNs ENODATA delegation-test.ventx.de
at QueryReqWrap.onresolve [as oncomplete] (dns.js:203:19) {
errno: undefined,
code: 'ENODATA',
syscall: 'queryNs',
hostname: 'delegation-test.ventx.de'
} undefined
Activity
bnoordhuis commentedon Jun 13, 2020
I can confirm what you're seeing but I don't think this is a Node.js bug. It might be a c-ares bug (the library Node.js uses to perform the NS query) but my hunch is that it's a problem with the DNS server.
Here is the response I get back:
Note how the answer count field is zero, even though there are clearly answers in the response packet:
The server acknowledges the query though because the question count field is one:
I didn't, ah, dig too deeply into what dig(1) does differently but on my system (and yours probably too since you use ubuntu too) it also consults systemd's 127.0.0.53 resolver:
I'm going to close this as not-our-bug but let me know if you have reason to believe it's a Node.js issue after all. You could try filing a bug report with c-ares.
iatpatelishan commentedon Sep 12, 2020
I was trying to do the same thing and found the same issue with dns implementation of nodejs. I dont know why it's closed as 'not-our-bug' if the nodejs official library is not returning the correct result (doesnt matter if it uses other library underneath which might have bug).
jo23sh commentedon Jan 13, 2021
Stumbled over this issue as well and did a bit of research. It seems to me that when for NS records at the nameservers of the parent zone, Route53 does include the NS records in the DNS response's AUTHORITY section, not in the ANSWER section. This is also the case in @f3lang's description above. The NS records are then included in the response's ANSWER section for queries targeted at the nameservers of the sub-zone (i.e., those contained in the NS records of the parent zone).
So my interpretation is that Node only returns the NS reccords if the response was contained in the ANSWER section and seems to ignore anything contained in the AUTHORITY section.
However, I'm not sure who is now misbehaving - would have to dig deeper in the RFCs for that. There are multiple possibilities:
A quick (and honestly, quite superficial) look into the c-ares source code gives me the impression that c-ares replies with ARES_NODATA if the answer count is zero, which is exactly what we are seeing with Route53's answers containing nothing in the ANSWER section.
Personally, I think this is an issue specific to how Route53 (correctly?) handles replying to NS queries and the expectations of the end-user. Getting back the contents of the AUTHORITY section in Node would be nice, but I guess there are limited use-cases for this and it would make the API unnecessarily complex for an edge-case.
A workaround for the initial issue seems simple: Just manually set the nameservers of the sub zone when querying, not the parent zone. Or don't set the nameservers manually at all (however, I guess there's a reason why you do set them manually).
bradh352 commentedon Oct 13, 2021
FYI, dig and the c-ares adig return the same results. There's no answer section in either, only authority. You need to use the right apis in c-ares to extract the authority section which most people have no desire to retrieve.
mjsztainbok commentedon Jul 1, 2022
If you query an authorative server, you are going to get an AUTHORITY section and not an ANSWER section. That is what is happening here. The DNS query is against the authoratative server in Route 53 so it is getting back an AUTHORITY seciton and not an ANSWER section. This would also happen if you do a query against another domain with one of the servers from its NS records outside of Route 53.