denoland/deno · error · NodeError

ERR_DNS_SET_SERVERS_FAILED

ERR_DNS_SET_SERVERS_FAILED

Error message

c-ares failed to set servers: "${err}" [${servers}]

What it means

After parsing, setServers() hands the tuple list to the native layer (_handle.setServers). If that returns nonzero, the polyfill first restores the previous server list (setServers rejoined from the originals), then throws ERR_DNS_SET_SERVERS_FAILED with the native error string and the servers value. It means entries survived JS parsing but the native resolver rejected them (bad ports, unsupported tuples) or the binding itself failed.

Source

Thrown at ext/node/polyfills/internal/dns/utils.ts:390

          return ArrayPrototypePush(newSet, [
            ipVersion,
            hostIP,
            NumberParseInt(port),
          ]);
        }
      }

      throw new ERR_INVALID_IP_ADDRESS(serv);
    });

    const errorNumber = this._handle.setServers(newSet);

    if (errorNumber !== 0) {
      // Reset the servers to the old servers, because ares probably unset them.
      this._handle.setServers(ArrayPrototypeJoin(orig, ","));
      const err = strerror(errorNumber);

      throw new ERR_DNS_SET_SERVERS_FAILED(
        err,
        ArrayPrototypeToString(servers),
      );
    }
  }

  /**
   * The resolver instance will send its requests from the specified IP address.
   * This allows programs to specify outbound interfaces when used on multi-homed
   * systems.
   *
   * If a v4 or v6 address is not specified, it is set to the default, and the
   * operating system will choose a local address automatically.
   *
   * The resolver will use the v4 local address when making requests to IPv4 DNS
   * servers, and the v6 local address when making requests to IPv6 DNS servers.
   * The `rrtype` of resolution requests has no impact on the local address used.
   *

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Retry with bare IP literals and no ports: setServers(['8.8.8.8', '1.1.1.1']).
  2. Validate host:port forms (integer port 1-65535) before calling.
  3. If valid input still fails, capture the servers array and native message and file a Deno issue - that indicates a polyfill/native-layer bug.

Example fix

// before
resolver.setServers(['8.8.8.8:0', '1.1.1.1']);

// after
resolver.setServers(['8.8.8.8', '1.1.1.1']);
Defensive patterns

Strategy: try-catch

Validate before calling

import { isIP } from 'node:net';

function hasValidPorts(servers) {
  return servers.every((s) => {
    const m = /^\[[0-9a-fA-F:]+\]:(\d+)$/.exec(s) || /^(\d+\.){3}\d+:(\d+)$/.exec(s);
    if (!m) return true; // no explicit port
    const p = Number(m[1] ?? m[2]);
    return Number.isInteger(p) && p >= 1 && p <= 65535;
  });
}
if (!hasValidPorts(servers)) throw new TypeError('bad port in DNS server list');

Try / catch

try {
  resolver.setServers(servers);
} catch (err) {
  if (err?.code === 'ERR_DNS_SET_SERVERS_FAILED') {
    logger.error('native layer rejected DNS servers; keeping previous config', err.message);
    // the polyfill already restored the old server list
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Ports that are 0, fractional or out of range ('8.8.8.8:0', '8.8.8.8:99999'); mixed or exotic tuple formats the native layer refuses; reconfiguring while a previous setServers failure left state behind.

Common situations: Dynamic DNS reconfiguration from loosely-validated config; feeding getServers() output round-tripped through JSON or string joins back into setServers; native binding edge cases in the polyfill.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/f4c4db3101cf7a95. Report an issue: GitHub.