Currently the DNS module seems to utf-8 encode the names passed to c-ares for DNS resolution: https://github.com/nodejs/node/blob/2c0a75118cd6a2eaf6b45fe8c67336f44c86ab0f/src/cares_wrap.cc#L1803
That doesn't work for internationalized domain names, which need to be IDNA encoded.
DNS is pretty much all ASCII, so IMHO Node shouldn't utf-8 encode on input.
Here is a list of international domain names to test.
This will produce an error:
> dns.resolve('espa帽a.icom.museum', function(r, e) { console.log(r, e) })`
> { Error: queryA ENOTFOUND espa帽a.icom.museum
at QueryReqWrap.onresolve [as oncomplete] (dns.js:197:19)
errno: 'ENOTFOUND',
code: 'ENOTFOUND',
syscall: 'queryA',
hostname: 'espa帽a.icom.museum' } undefined
Whereas the proper IDNA encoded version works:
> dns.resolve('xn--espaa-rta.icom.museum', function(e, r) { console.log(e, r) })
> null [ '91.194.60.138' ]
All supported versions of Node are affected. I'm looking into it.
Possible fix in https://github.com/nodejs/node/pull/25559
I'm quite surprised that this affects so many version. I'm pretty sure IDN did work at least at some point in time.
@santigimeno and I opened PRs but now that I think about it, this issue should be fixed once v10.x upgrades to libuv v1.24.0 because that's the first libuv release that includes https://github.com/libuv/libuv/pull/2046.
Landing the PRs would still be useful for:
I'm pretty sure IDN did work at least at some point in time.
@silverwind If you'll allow me to self-quote from https://github.com/nodejs/node/pull/25679#issue-247231927:
[..] Node.js left it up to the system resolver or c-ares.
Leaving it to the system resolver introduces platform differences
because:
some support IDNA 2008
some only IDNA 2003 (glibc until 2.28), and
some don't support IDNA at all (musl libc)
In other words, Node's behavior is currently platform-dependent (bad.)