{"record":{"id":"563743bee0e3584b","repo":"nodejs/node","slug":"und-err-socks5-reply-version","errorCode":"UND_ERR_SOCKS5_REPLY_VERSION","errorMessage":"Invalid SOCKS version in reply: ${version}","messagePattern":"Invalid SOCKS version in reply: (.+?)","errorType":"exception","errorClass":"Socks5ProxyError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/core/socks5-client.js","lineNumber":328,"sourceCode":"    request.writeUInt16BE(port, 4 + addressBuffer.length)\n\n    return request\n  }\n\n  /**\n   * Handle CONNECT response\n   */\n  handleConnectResponse () {\n    if (this.buffer.length < 4) {\n      return // Not enough data for header\n    }\n\n    const version = this.buffer[0]\n    const reply = this.buffer[1]\n    const addressType = this.buffer[3]\n\n    if (version !== SOCKS_VERSION) {\n      throw new Socks5ProxyError(`Invalid SOCKS version in reply: ${version}`, 'UND_ERR_SOCKS5_REPLY_VERSION')\n    }\n\n    // Calculate the expected response length\n    let responseLength = 4 // VER + REP + RSV + ATYP\n    if (addressType === ADDRESS_TYPES.IPV4) {\n      responseLength += 4 + 2 // IPv4 + port\n    } else if (addressType === ADDRESS_TYPES.DOMAIN) {\n      if (this.buffer.length < 5) {\n        return // Need domain length byte\n      }\n      responseLength += 1 + this.buffer[4] + 2 // length byte + domain + port\n    } else if (addressType === ADDRESS_TYPES.IPV6) {\n      responseLength += 16 + 2 // IPv6 + port\n    } else {\n      throw new Socks5ProxyError(`Invalid address type in reply: ${addressType}`, 'UND_ERR_SOCKS5_ADDR_TYPE')\n    }\n\n    if (this.buffer.length < responseLength) {","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/core/socks5-client.js#L310-L346","documentation":"Thrown in handleConnectResponse() when the VER byte of the CONNECT reply is not SOCKS_VERSION (0x05). Like the handshake version check, this catches a non-SOCKS5 or desynchronized reply at the final CONNECT stage.","triggerScenarios":"Server sends a reply without the VER byte; buffer desync leaves bytes from the auth reply still in this.buffer; the endpoint behind the proxy is not SOCKS5-compliant; a MITM injects non-SOCKS data.","commonSituations":"Framing bug where prior reply bytes were not fully consumed; buggy server omitting VER; reconnect over a corrupted socket.","solutions":["Ensure the auth/handshake replies were fully consumed so this.buffer starts at the CONNECT reply.","Reconnect on a fresh socket to clear desync.","Capture the byte stream to confirm the server's CONNECT reply format.","Test against a reference SOCKS5 server to rule out client-side framing."],"exampleFix":"// no caller config fixes a desync/non-conformant reply;\n// reset state with a fresh client + socket:\n//   socket.destroy(); client = new Socks5Client(newSocket, opts); client.handshake();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { /* wait for connect response */ } catch (e) {\n  if (e.code === 'UND_ERR_SOCKS5_REPLY_VERSION') {\n    // desync or non-conformant server; reconnect on a fresh socket\n  } else throw e\n}","preventionTips":["Fully consume each reply so this.buffer starts at the next frame.","Reconnect fresh after any protocol desync.","Capture a trace to confirm the server's CONNECT reply VER byte."],"tags":["socks5","proxy","protocol","network","state-machine"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}