XTLS/Xray-core · error

failed to read request

Error message

failed to read request

What it means

Thrown in handshake5 (proxy/socks/protocol.go:157) when reading the 3-byte SOCKS5 request header (VER, CMD, RSV) fails after authentication. ReadFullFrom demands exactly 3 bytes; a short read means the client ended, reset, or stalled before sending its request.

Source

Thrown at proxy/socks/protocol.go:157

	return "", nil
}

func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer net.Conn) (*protocol.RequestHeader, *TempUDPConn, error) {
	var (
		username string
		err      error
	)
	if username, err = s.auth5(nMethod, reader, writer); err != nil {
		return nil, nil, err
	}

	var cmd byte
	{
		buffer := buf.StackNew()
		if _, err := buffer.ReadFullFrom(reader, 3); err != nil {
			buffer.Release()
			return nil, nil, errors.New("failed to read request").Base(err)
		}
		cmd = buffer.Byte(1)
		buffer.Release()
	}

	request := new(protocol.RequestHeader)
	if username != "" {
		request.User = &protocol.MemoryUser{Email: username}
	}
	switch cmd {
	case cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR:
		// We don't have a solution for Tor case now. Simply treat it as connect command.
		request.Command = protocol.RequestCommandTCP
	case cmdUDPAssociate:
		if !s.config.UdpEnabled {
			writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
			return nil, nil, errors.New("UDP is not enabled.")
		}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Confirm the client sends VER=0x05, CMD, RSV=0x00 immediately after auth completes and reads the auth reply first.
  2. Inspect the base error: EOF = client left on purpose (usually benign); timeout = stalled session.
  3. If using a test tool, use one that performs the full handshake (curl with socks5h is a good reference).

Example fix

// before: client never reads the auth reply and closes
writeAuth(conn); conn.Close()

// after: read reply, then send the CONNECT request
io.ReadFull(conn, make([]byte, 2)) // 0x01 0x00
conn.Write([]byte{0x05, 0x01, 0x00, 0x03, 0x0B, 'e','x','a','m','p','l','e','.','c','o','m', 0x00, 0x50})
Defensive patterns

Strategy: try-catch

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to read request") {
    logDebug("peer disappeared after SOCKS5 auth")
    conn.Close()
}

Prevention

When it happens

Trigger: Client completes auth negotiation then disconnects (credential-testing tools that only verify auth); malformed clients sending 2 bytes; connection cut by NAT idle timers between auth and request.

Common situations: Credential-checker scripts that stop after auth; flaky networks; clients that pipeline incorrectly and desynchronize the stream after a failed auth attempt in a previous connection.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/e775a359e05a56bf. Report an issue: GitHub.