nodejs/node · error · Socks5ProxyError

UND_ERR_SOCKS5_ADDR_TYPE

UND_ERR_SOCKS5_ADDR_TYPE

Error message

Invalid address type in reply: ${addressType}

What it means

Thrown in handleConnectResponse() when the ATYP (address type) byte of the CONNECT reply is not IPV4 (0x01), DOMAIN (0x03), or IPV6 (0x04). The bound-address field in RFC 1928 replies uses only those three ATYP values; anything else is malformed.

Source

Thrown at deps/undici/src/lib/core/socks5-client.js:343

    const addressType = this.buffer[3]

    if (version !== SOCKS_VERSION) {
      throw new Socks5ProxyError(`Invalid SOCKS version in reply: ${version}`, 'UND_ERR_SOCKS5_REPLY_VERSION')
    }

    // Calculate the expected response length
    let responseLength = 4 // VER + REP + RSV + ATYP
    if (addressType === ADDRESS_TYPES.IPV4) {
      responseLength += 4 + 2 // IPv4 + port
    } else if (addressType === ADDRESS_TYPES.DOMAIN) {
      if (this.buffer.length < 5) {
        return // Need domain length byte
      }
      responseLength += 1 + this.buffer[4] + 2 // length byte + domain + port
    } else if (addressType === ADDRESS_TYPES.IPV6) {
      responseLength += 16 + 2 // IPv6 + port
    } else {
      throw new Socks5ProxyError(`Invalid address type in reply: ${addressType}`, 'UND_ERR_SOCKS5_ADDR_TYPE')
    }

    if (this.buffer.length < responseLength) {
      return // Not enough data for full response
    }

    if (reply !== REPLY_CODES.SUCCEEDED) {
      const errorMessage = this.getReplyErrorMessage(reply)
      throw new Socks5ProxyError(`SOCKS5 connection failed: ${errorMessage}`, `UND_ERR_SOCKS5_REPLY_${reply}`)
    }

    // Parse bound address and port
    let boundAddress
    let offset = 4

    if (addressType === ADDRESS_TYPES.IPV4) {
      boundAddress = Array.from(this.buffer.subarray(offset, offset + 4)).join('.')
      offset += 4

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Confirm the full CONNECT reply header (VER+REP+RSV+ATYP) is being read at the correct offset.
  2. Reconnect on a fresh socket to eliminate desync.
  3. Log the raw ATYP byte and surrounding bytes to detect framing issues.
  4. Test against a known-good SOCKS5 server.

Example fix

// diagnosing: log raw bytes
// debug('connect reply head', this.buffer.subarray(0, 8))
// then reconnect on a fresh socket if desync is confirmed
Defensive patterns

Strategy: try-catch

Try / catch

try { /* wait for connect response */ } catch (e) {
  if (e.code === 'UND_ERR_SOCKS5_ADDR_TYPE') {
    // unexpected ATYP; verify framing or switch proxy
  } else throw e
}

Prevention

When it happens

Trigger: Server returns an unknown ATYP; buffer desync shifts the byte being interpreted as ATYP; buggy server using a reserved ATYP value.

Common situations: Desync from an incompletely consumed prior reply; a proxy that prepends extra header bytes; protocol parser bug.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/217372293aae2213. Report an issue: GitHub.