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
- Inspect the logged Base error (and the AccessRejected record) to identify the actual handshake stage that failed.
- For auth failures, correct the client credentials to match inbound users.
- For timeouts, increase policy.timeouts.handshake (level 0 policy) on the server.
- 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
- Log at debug level to capture the underlying handshake error.
- Keep policy handshake timeouts above client RTT.
- Monitor rejected-access records for credential-brute-force patterns.
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
- unexpected server version: {version}
- auth method not supported.
- failed to read from connection
- unknown network: {network}
- inbound gateway not specified
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/7020c2d7f0c4df8f.
Report an issue: GitHub.