denoland/deno · error · Error
${bindingName} ${errCodeMessage} ${name}
Error message
${bindingName} ${errCodeMessage} ${name} What it means
dns.promises/resolve query() calls the native c-ares binding via this._handle[bindingName](req, toASCII(name)). If the binding returns a nonzero error code, dnsException(err, bindingName, name) builds and throws a Node-style DNS error whose message includes the binding name, the error code/message (e.g. ENOTFOUND, ESERVFAIL) and the queried name.
Source
Thrown at ext/node/polyfills/dns.ts:435
if (isResolveCallback(options)) {
callback = options;
options = {};
}
validateString(name, "name");
validateFunction(callback, "callback");
const req = new QueryReqWrap();
req.bindingName = bindingName;
req.callback = callback as ResolveCallback;
req.hostname = name;
req.oncomplete = onresolve;
req.ttl = !!(options && (options as ResolveOptions).ttl);
const err = this._handle[bindingName](req, toASCII(name));
if (err) {
throw dnsException(err, bindingName, name);
}
return req;
}
ObjectDefineProperty(query, "name", {
__proto__: null,
value: bindingName,
});
return query;
}
const resolveMap = ObjectCreate(null);
class Resolver extends CallbackResolver {
constructor(options?: ResolverOptions) {
super(options);View on GitHub (pinned to a961cdec3b)
Solutions
- Catch the error and inspect err.code (ENOTFOUND/ESERVFAIL/ECONNREFUSED) to decide between fixing the name and retrying with fallback resolvers.
- Retry with a public resolver via a dns.Resolver({ servers: ['8.8.8.8'] }) when the system resolver is broken.
- Verify the hostname spelling and that it is a name (not an IP) — resolve* APIs require hostnames; use dns.lookup for literals.
- Check /etc/resolv.conf and network/VPN settings if all queries fail.
Example fix
// before
const addrs = await dns.promises.resolve4('unknown.example'); // throws ENOTFOUND
// after
try {
const addrs = await dns.promises.resolve4('unknown.example');
} catch (err) {
if (err.code === 'ENOTFOUND') {
const resolver = new dns.promises.Resolver({ servers: ['8.8.8.8'] });
return resolver.resolve4('unknown.example');
}
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
function assertResolvableName(name) {
if (!name || typeof name !== 'string') throw new TypeError('hostname required');
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(name)) {
throw new TypeError('use dns.lookup for IP literals, not dns.resolve*');
}
toASCII(name); // throws early on malformed IDN
} Type guard
function isHostname(name) {
return typeof name === 'string' && name.length > 0 && !net.isIP(name);
} Try / catch
try {
return await dns.promises.resolve4(name);
} catch (err) {
if (err.code === 'ENOTFOUND') return []; // name does not exist
if (['ESERVFAIL', 'ETIMEOUT', 'ECONNREFUSED'].includes(err.code)) {
// retry with fallback resolver
const r = new dns.promises.Resolver({ servers: ['8.8.8.8', '1.1.1.1'] });
return r.resolve4(name);
}
throw err;
} Prevention
- Always inspect err.code to distinguish 'name doesn't exist' from 'resolver unreachable'.
- Configure a fallback Resolver with public nameservers for production lookups.
- Convert IP literals with dns.lookup, not dns.resolve*.
- Timeout-wrap lookups (Promise.race) so resolver outages fail fast.
When it happens
Trigger: dns.resolve*/dns.promises.resolve* failing synchronously at the c-ares layer — e.g. NXDOMAIN for an unknown name, SERVFAIL/timeout from resolvers, malformed internationalized names after toASCII punycode conversion, or no configured nameservers.
Common situations: Resolving a hostname that doesn't exist; DNS server outages or blocked UDP/53 in containers; resolv.conf misconfiguration; IDN names that fail punycode conversion.
Related errors
- Expected data to be a string, Buffer, Uint8Array, or ArrayBu
- TLS wrap attach failed: ${attachResult}
- TLS wrap attach (JS stream) failed: ${attachResult}
- ERR_INVALID_FD_TYPE
- ERR_INVALID_ARG_TYPE
AI-assisted analysis of denoland/deno@a961cdec3b (2026-09-03).
Data as JSON: /api/errors/d29ba49c6b0c4752.
Report an issue: GitHub.