denoland/deno · error · TypeError
ERR_INVALID_IP_ADDRESS
ERR_INVALID_IP_ADDRESS
Error message
Invalid IP address: ${localAddress} What it means
During net.connect(), _lookupAndConnect validates options.localAddress with isIP(): it must be a local IP literal, because the value is passed straight to bind() — no DNS resolution happens for it. A hostname (even 'localhost') or malformed IP throws ERR_INVALID_IP_ADDRESS before the connection starts.
Source
Thrown at ext/node/polyfills/net.ts:1060
}
socket[kBuffer] = userBuf;
}
socket._handle.useUserBuffer(userBuf);
}
}
}
function _lookupAndConnect(self: Socket, options: TcpSocketConnectOptions) {
const { localAddress, localPort } = options;
const host = options.host || "localhost";
let { port, autoSelectFamilyAttemptTimeout, autoSelectFamily } = options;
validateStringWithoutNullBytes(host, "options.host");
if (localAddress && !isIP(localAddress)) {
throw new ERR_INVALID_IP_ADDRESS(localAddress);
}
if (localPort) {
validateNumber(localPort, "options.localPort");
}
if (typeof port !== "undefined") {
if (typeof port !== "number" && typeof port !== "string") {
throw new ERR_INVALID_ARG_TYPE(
"options.port",
["number", "string"],
port,
);
}
validatePort(port);
}
View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Pass an IP literal for localAddress: '127.0.0.1', '10.0.0.5', '::1'
- If the source is a hostname, resolve it first with dns.lookup(host) and use the returned address
- Pre-validate with net.isIP(localAddress) !== 0 and fall back to default (omit localAddress)
Example fix
// before
net.connect({ port, host, localAddress: cfg.localHost }); // hostname -> throws
// after
const localAddress = net.isIP(cfg.localHost) ? cfg.localHost : undefined;
net.connect({ port, host, localAddress }); Defensive patterns
Strategy: validation
Validate before calling
const localAddress = net.isIP(cfg.localHost ?? '') !== 0
? cfg.localHost
: undefined; // omit rather than pass a hostname
net.connect({ port, host, localAddress }); Type guard
function isIpLiteral(v: unknown): v is string {
return typeof v === 'string' && net.isIP(v) !== 0;
} Try / catch
try {
socket = net.connect({ port, host, localAddress });
} catch (e: any) {
if (e?.code === 'ERR_INVALID_IP_ADDRESS') {
socket = net.connect({ port, host }); // retry without localAddress binding
} else throw e;
} Prevention
- localAddress takes IP literals only — resolve hostnames with dns.lookup first
- Validate config-provided local addresses with net.isIP() at load time
- Do not copy the host option's hostname semantics onto localAddress
When it happens
Trigger: net.connect({ port, host: 'example.com', localAddress: 'example.com' }); localAddress: 'localhost' (a hostname, not an IP); localAddress: '192.168.1.999'; a config/env var supplying a hostname into localAddress.
Common situations: Multi-homed servers binding egress traffic to a specific NIC by name instead of address; copying the host option's semantics onto localAddress; IPv6 addresses missing or misplaced (e.g. missing brackets does not matter, but a bare zone-id does).
Related errors
- ERR_INVALID_ARG_TYPE
- TLS wrap attach failed: ${attachResult}
- TLS wrap attach (JS stream) failed: ${attachResult}
- ERR_INVALID_FD_TYPE
- ERR_INVALID_ARG_VALUE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/f13359b6f7046734.
Report an issue: GitHub.