XTLS/Xray-core · error

failed to read request

Error message

failed to read request

What it means

Generic wrapper thrown when the SOCKS ServerSession.Handshake (SOCKS4/4a/5 negotiation including auth and request parsing) fails for any reason; the real cause is in the Base error chain. It also records an AccessRejected log entry when the source is known.

Source

Thrown at proxy/socks/server.go:133

	// Firstbyte is for forwarded conn from SOCKS inbound
	// Because it needs first byte to choose protocol
	// We need to add it back
	reader := &buf.BufferedReader{
		Reader: buf.NewReader(conn),
		Buffer: buf.MultiBuffer{buf.FromBytes(firstbyte)},
	}
	request, tempUDPConn, err := svrSession.Handshake(reader, conn)
	defer common.CloseIfExists(tempUDPConn)
	if err != nil {
		if inbound.Source.IsValid() {
			log.Record(&log.AccessMessage{
				From:   inbound.Source,
				To:     "",
				Status: log.AccessRejected,
				Reason: err,
			})
		}
		return errors.New("failed to read request").Base(err)
	}
	if request.User != nil {
		inbound.User.Email = request.User.Email
	}

	if err := conn.SetReadDeadline(time.Time{}); err != nil {
		errors.LogInfoInner(ctx, err, "failed to clear deadline")
	}

	if request.Command == protocol.RequestCommandTCP {
		dest := request.Destination()
		errors.LogInfo(ctx, "TCP Connect request to ", dest)
		if inbound.Source.IsValid() {
			ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
				From:   inbound.Source,
				To:     dest,
				Status: log.AccessAccepted,
				Reason: "",

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Inspect the logged Base error (and the AccessRejected record) to identify the actual handshake stage that failed.
  2. For auth failures, correct the client credentials to match inbound users.
  3. For timeouts, increase policy.timeouts.handshake (level 0 policy) on the server.
  4. Enable debug logging (loglevel: debug) to capture the exact malformed request.
Defensive patterns

Strategy: try-catch

Try / catch

if err := s.processTCP(ctx, conn, dispatcher, first); err != nil {
	if base := errors.HasType(err, ...); strings.Contains(err.Error(), "failed to read request") {
		log.Record(&log.AccessMessage{Status: log.AccessRejected, Reason: err})
		return nil // per-connection failure, keep listener alive
	}
}

Prevention

When it happens

Trigger: Any handshake sub-failure: malformed SOCKS request bytes, auth rejection from the inbound's users list, unsupported command, or a read timeout within policy.Timeouts.Handshake. Triggered per-connection at svrSession.Handshake in processTCP.

Common situations: Clients with wrong credentials hitting an auth-enabled SOCKS inbound; scanners sending garbage; slow clients exceeding the handshake timeout; client libraries speaking a nonstandard SOCKS dialect.

Related errors


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