denoland/deno · error · Error
Invalid IP address: ${addr0}
Error message
Invalid IP address: ${addr0} What it means
ChannelWrap's lookup-like methods accept a primary local address (addr0) that must be a valid IPv4 or IPv6 literal. The address is validated with isIPv4/isIPv6 before being stored in #localAddress for use with c-ares name resolution. If addr0 parses as neither, this error is thrown to prevent passing a malformed binding address to the resolver.
Source
Thrown at ext/node/polyfills/internal_binding/cares_wrap.ts:926
setLocalAddress(addr0: string, addr1?: string) {
// Mirror Node's c-ares `ChannelWrap::SetLocalAddress`: the first argument
// may be either an IPv4 or IPv6 address; if a second argument is given it
// must be the *other* family (so exactly one IPv4 and one IPv6 address, in
// either order). The caller (`Resolver.setLocalAddress` in
// `internal/dns/utils.ts`) has already validated the arguments are strings.
//
// We validate the addresses here and record them so the call no longer
// throws and matches Node's observable behavior. The underlying resolver op
// (`op_dns_resolve`) does not yet expose a per-query bind address, so the
// stored value is not applied to outgoing queries; see
// https://github.com/denoland/deno/issues/36518.
let type0: 4 | 6;
if (isIPv4(addr0)) {
type0 = 4;
} else if (isIPv6(addr0)) {
type0 = 6;
} else {
throw new Error(`Invalid IP address: ${addr0}`);
}
if (addr1 !== undefined) {
if (isIPv4(addr1)) {
if (type0 === 4) {
throw new Error("Cannot specify two IPv4 addresses");
}
} else if (isIPv6(addr1)) {
if (type0 === 6) {
throw new Error("Cannot specify two IPv6 addresses");
}
} else {
throw new Error(`Invalid IP address: ${addr1}`);
}
}
this.#localAddress = {
ipv4: type0 === 4 ? addr0 : addr1,View on GitHub (pinned to a961cdec3b)
Solutions
- Pass a valid IP literal (e.g. '0.0.0.0', '::') instead of a hostname in the localAddress option.
- Validate the string with isIPv4/isIPv6 (or a regex) before passing it to the resolver.
- Resolve a hostname to an IP first (dns.lookup) if you only have a name, then pass the resulting literal.
Example fix
// before
const resolver = new dns.Resolver({ localAddress: 'my-host.internal' });
// after
const addresses = await dns.promises.lookup('my-host.internal');
const resolver = new dns.Resolver({ localAddress: addresses[0].address }); Defensive patterns
Strategy: validation
Validate before calling
function isValidIp(addr) {
const v4 = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;
const v6 = /^[0-9a-fA-F:]+$/; // plus a strict isIPv6 check
return v4.test(addr) || isIPv6(addr);
}
if (!isValidIp(addr0)) throw new Error(`Refusing to bind local address: ${addr0}`); Type guard
function isIpLiteral(addr) {
return typeof addr === 'string' && (isIPv4(addr) || isIPv6(addr));
} Try / catch
try {
channel.lookup(...);
} catch (err) {
if (String(err.message).startsWith('Invalid IP address')) {
// fall back to no localAddress binding
}
} Prevention
- Always pass IP literals, never hostnames, as localAddress options.
- Run addresses through isIPv4/isIPv6 at config load time and fail fast.
- Resolve hostnames to addresses once at startup, then cache the literals.
When it happens
Trigger: Calling ChannelWrap methods that accept a local address (e.g. getAddrInfo/lookup via the Resolver with a localAddress option) where addr0 is not a valid IPv4 or IPv6 literal — e.g. a hostname like 'localhost', an empty string, or a typo like '192.168.1.256'.
Common situations: Passing a hostname instead of an IP literal in dns.Resolver localAddress/localPort options; reading the address from config or an env var that contains a name rather than a literal; IPv6 written with a zone index or invalid shorthand that fails strict parsing.
Related errors
- Cannot specify two IPv4 addresses
- Cannot specify two IPv6 addresses
- Invalid IP address: ${addr1}
- invalid ${name}, must not be infinity or NaN
- ERR_INVALID_HTTP_TOKEN
AI-assisted analysis of denoland/deno@a961cdec3b (2026-09-03).
Data as JSON: /api/errors/41785ffa116d6354.
Report an issue: GitHub.