denoland/deno · error · Error

Invalid IP address: ${addr1}

Error message

Invalid IP address: ${addr1}

What it means

The secondary local address (addr1) must also be a valid IPv4 or IPv6 literal. When addr0 was accepted but addr1 fails both isIPv4 and isIPv6, this error is thrown. The stored #localAddress only supports strict IP literals, so anything else (hostnames, empty strings, malformed IPv6) is rejected.

Source

Thrown at ext/node/polyfills/internal_binding/cares_wrap.ts:939

    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,
      ipv6: type0 === 6 ? addr0 : addr1,
    };
  }

  cancel() {
    for (const req of new SafeSetIterator(this.#pendingQueries)) {
      req.oncomplete("ECANCELLED", []);
    }
    SetPrototypeClear(this.#pendingQueries);

    // Abort in-flight DNS operations so the process can exit.
    for (const rid of new SafeSetIterator(this.#cancelRids)) {
      core.tryClose(rid);

View on GitHub (pinned to a961cdec3b)

Solutions

  1. Validate each address with isIPv4/isIPv6 before passing it and fix the malformed one.
  2. Pass undefined instead of an empty/invalid string when no secondary address is needed.
  3. Strip zone indices/whitespace and normalize the address string first.

Example fix

// before
new ChannelWrap('0.0.0.0', 'localhost'); // hostname not allowed
// after
new ChannelWrap('0.0.0.0', '::1'); // use an IP literal
Defensive patterns

Strategy: validation

Validate before calling

for (const a of [addr0, addr1]) {
  if (a !== undefined && !(isIPv4(a) || isIPv6(a))) {
    throw new Error(`Not an IP literal: ${a}`);
  }
}

Type guard

function isStrictIp(a) {
  return a === undefined || (typeof a === 'string' && (isIPv4(a) || isIPv6(a)));
}

Try / catch

try {
  channel.lookup(req, hostname);
} catch (err) {
  if (String(err.message).startsWith('Invalid IP address')) {
    // unset the offending local address and retry
  }
}

Prevention

When it happens

Trigger: Calling a ChannelWrap lookup with a valid primary address but a malformed secondary address, e.g. localAddresses: ['0.0.0.0', 'localhost'] or a truncated IPv6 like 'fe80::1%'.

Common situations: Splitting an 'address:port' or CIDR string that leaves garbage in the second element; env/config where the second address field is empty or contains a zone-indexed IPv6 unsupported by strict parsing.

Related errors


AI-assisted analysis of denoland/deno@a961cdec3b (2026-09-03). Data as JSON: /api/errors/7387645ea78c9146. Report an issue: GitHub.