honojs/hono · error · TypeError

ERR_INVALID_IP_ADDRESS

ERR_INVALID_IP_ADDRESS

Error message

Invalid IPv4 address: ${ipv4}

What it means

Hono's ipaddr utility throws a TypeError (code ERR_INVALID_IP_ADDRESS) when a string passed to convertIPv4ToBinary cannot be parsed as a dotted-quad IPv4 address. It is used by CIDR/IP matchers, so malformed IPv4 inputs (wrong octet count, out-of-range octets, non-numeric characters) surface here.

Source

Thrown at src/utils/ipaddr.ts:77

 */
export const distinctRemoteAddr = (remoteAddr: string): AddressType => {
  if (IPV4_REGEX.test(remoteAddr)) {
    return 'IPv4'
  }
  if (remoteAddr.includes(':')) {
    // Domain can't include `:`
    return 'IPv6'
  }
}

const createInvalidIPAddressError = (message: string): InvalidIPAddressError => {
  const error = new TypeError(message) as InvalidIPAddressError
  error.code = INVALID_IP_ADDRESS_ERROR_CODE
  return error
}

const throwInvalidIPv4Address = (ipv4: string): never => {
  throw createInvalidIPAddressError(`Invalid IPv4 address: ${ipv4}`)
}

const throwInvalidIPv6Address = (ipv6: string): never => {
  throw createInvalidIPAddressError(`Invalid IPv6 address: ${ipv6}`)
}

const parseIPv4ToBinary = (
  ipv4: string,
  start: number,
  end: number,
  onInvalid: () => never
): bigint => {
  let result = 0n
  let octets = 0
  let octet = 0
  let digits = 0
  let firstDigit = 0

View on GitHub (pinned to e2740d5a1b)

Solutions

  1. Validate with a regex or net.isIP-style check before converting
  2. Trim/split x-forwarded-for and pick the first well-formed entry
  3. Fix the typo in your configured IP/CIDR rules
  4. Branch on ':' in the address to route IPv6 strings to convertIPv6ToBinary

Example fix

// before
const bin = convertIPv4ToBinary(addr) // throws on '1.2.3.4.5'

// after
const IPV4_RE = /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/
if (IPV4_RE.test(addr)) {
  const bin = convertIPv4ToBinary(addr)
} else {
  // handle invalid address
}
Defensive patterns

Strategy: type-guard

Validate before calling

const IPV4_RE = /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/
if (IPV4_RE.test(addr)) convertIPv4ToBinary(addr)

Type guard

const isIPv4 = (s: string): boolean =>
  /^((25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(25[0-5]|2[0-4]\d|1?\d?\d)$/.test(s.trim())

Try / catch

try {
  return convertIPv4ToBinary(addr)
} catch (e) {
  if (e instanceof TypeError && (e as InvalidIPAddressError).code === 'ERR_INVALID_IP_ADDRESS') {
    // treat as invalid input: skip or reject
    return null
  }
  throw e
}

Prevention

When it happens

Trigger: Calling convertIPv4ToBinary (directly or via CIDR matching in ipRestriction / range utilities) with strings like '1.2.3', '1.2.3.4.5', '256.1.1.1', '1.2.3.abc', or an IPv6 string accidentally passed to the IPv4 path.

Common situations: Feeding user-supplied or header-derived strings (x-forwarded-for entries) into CIDR matchers without validation; config typos in allowRules/denyRules such as '192.168.1' or '192.168.1.256'; passing a hostname instead of an IP.

Related errors


AI-assisted analysis of honojs/hono@e2740d5a1b (2026-08-28). Data as JSON: /api/errors/c88192f88b9c47b5. Report an issue: GitHub.