nodejs/node · error · Socks5ProxyError

UND_ERR_SOCKS5_AUTH_VERSION

UND_ERR_SOCKS5_AUTH_VERSION

Error message

Invalid auth sub-negotiation version: ${version}

What it means

Thrown in handleAuthResponse() when the first byte of the username/password auth reply is not 0x01. RFC 1929 fixes the sub-negotiation version at 0x01; any other value indicates a non-conformant server or protocol desynchronization (e.g. leftover bytes from the method-selection reply being parsed as the auth reply).

Source

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

    request[2 + usernameBuffer.length] = passwordBuffer.length
    passwordBuffer.copy(request, 3 + usernameBuffer.length)

    this.socket.write(request)
  }

  /**
   * Handle authentication response
   */
  handleAuthResponse () {
    if (this.buffer.length < 2) {
      return // Not enough data yet
    }

    const version = this.buffer[0]
    const status = this.buffer[1]

    if (version !== 0x01) {
      throw new Socks5ProxyError(`Invalid auth sub-negotiation version: ${version}`, 'UND_ERR_SOCKS5_AUTH_VERSION')
    }

    if (status !== 0x00) {
      throw new Socks5ProxyError('Authentication failed', 'UND_ERR_SOCKS5_AUTH_FAILED')
    }

    this.buffer = this.buffer.subarray(2)
    debug('authentication successful')
    this.markAuthenticated()
  }

  /**
   * Send CONNECT command
   * @param {string} address - Target address (IP or domain)
   * @param {number} port - Target port
   */
  connect (address, port) {
    if (this.state === STATES.CONNECTING || this.state === STATES.CONNECTED) {

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Verify the proxy implements RFC 1929 username/password auth correctly.
  2. Check that the client correctly consumed the prior handshake reply (buffer framing).
  3. Reconnect on a fresh socket to rule out desync from a partial earlier read.
  4. Capture the exchange with a packet trace to confirm the server's reply byte.

Example fix

// no caller-side config fixes a non-conformant server;
// verify with a known-good proxy and a packet capture:
//   expected server reply: 01 00  (VER=1, STATUS=success)
Defensive patterns

Strategy: try-catch

Try / catch

try { /* wait for auth response */ } catch (e) {
  if (e.code === 'UND_ERR_SOCKS5_AUTH_VERSION') {
    // server is not RFC 1929 compliant or buffers desynced; reconnect fresh
  } else throw e
}

Prevention

When it happens

Trigger: Server does not follow RFC 1929 and uses a different version byte; buffer desync where handleAuthResponse reads bytes belonging to a different phase; a SOCKS5 server that skipped the auth sub-negotiation.

Common situations: Buggy/incomplete SOCKS5 server; framing bug causing stale bytes in this.buffer; proxy that proxies GSSAPI but was negotiated as USERNAME_PASSWORD.

Related errors


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