{"record":{"id":"f4c4db3101cf7a95","repo":"denoland/deno","slug":"err-dns-set-servers-failed","errorCode":"ERR_DNS_SET_SERVERS_FAILED","errorMessage":"c-ares failed to set servers: \"${err}\" [${servers}]","messagePattern":"c-ares failed to set servers: \"(.+?)\" \\[(.+?)\\]","errorType":"exception","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/dns/utils.ts","lineNumber":390,"sourceCode":"          return ArrayPrototypePush(newSet, [\n            ipVersion,\n            hostIP,\n            NumberParseInt(port),\n          ]);\n        }\n      }\n\n      throw new ERR_INVALID_IP_ADDRESS(serv);\n    });\n\n    const errorNumber = this._handle.setServers(newSet);\n\n    if (errorNumber !== 0) {\n      // Reset the servers to the old servers, because ares probably unset them.\n      this._handle.setServers(ArrayPrototypeJoin(orig, \",\"));\n      const err = strerror(errorNumber);\n\n      throw new ERR_DNS_SET_SERVERS_FAILED(\n        err,\n        ArrayPrototypeToString(servers),\n      );\n    }\n  }\n\n  /**\n   * The resolver instance will send its requests from the specified IP address.\n   * This allows programs to specify outbound interfaces when used on multi-homed\n   * systems.\n   *\n   * If a v4 or v6 address is not specified, it is set to the default, and the\n   * operating system will choose a local address automatically.\n   *\n   * The resolver will use the v4 local address when making requests to IPv4 DNS\n   * servers, and the v6 local address when making requests to IPv6 DNS servers.\n   * The `rrtype` of resolution requests has no impact on the local address used.\n   *","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/dns/utils.ts#L372-L408","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Retry with bare IP literals and no ports: setServers(['8.8.8.8', '1.1.1.1']).","Validate host:port forms (integer port 1-65535) before calling.","If valid input still fails, capture the servers array and native message and file a Deno issue - that indicates a polyfill/native-layer bug."],"exampleFix":"// before\nresolver.setServers(['8.8.8.8:0', '1.1.1.1']);\n\n// after\nresolver.setServers(['8.8.8.8', '1.1.1.1']);","handlingStrategy":"try-catch","validationCode":"import { isIP } from 'node:net';\n\nfunction hasValidPorts(servers) {\n  return servers.every((s) => {\n    const m = /^\\[[0-9a-fA-F:]+\\]:(\\d+)$/.exec(s) || /^(\\d+\\.){3}\\d+:(\\d+)$/.exec(s);\n    if (!m) return true; // no explicit port\n    const p = Number(m[1] ?? m[2]);\n    return Number.isInteger(p) && p >= 1 && p <= 65535;\n  });\n}\nif (!hasValidPorts(servers)) throw new TypeError('bad port in DNS server list');","typeGuard":null,"tryCatchPattern":"try {\n  resolver.setServers(servers);\n} catch (err) {\n  if (err?.code === 'ERR_DNS_SET_SERVERS_FAILED') {\n    logger.error('native layer rejected DNS servers; keeping previous config', err.message);\n    // the polyfill already restored the old server list\n  } else {\n    throw err;\n  }\n}","preventionTips":["Keep it simple: pass bare IP literals without ports when possible.","Snapshot getServers() before setServers so you can report or restore config on failure.","Treat setServers as a fallible config operation: validate input, log failures, keep the process alive."],"tags":["dns","set-servers","c-ares","resolver","configuration"],"backgroundTag":"dns-server-configuration","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}