XTLS/Xray-core · error

failed to read from connection

Error message

failed to read from connection

What it means

Thrown by the SOCKS inbound when reading the first byte of a TCP connection fails with something other than a clean immediate EOF. The first byte determines whether the connection is SOCKS5 (0x05), SOCKS4/4a (0x04), or should be re-parsed as HTTP. A zero-byte read with a non-EOF error (reset, timeout, TLS garbage) lands here.

Source

Thrown at proxy/socks/server.go:85

	inbound := session.InboundFromContext(ctx)
	inbound.Name = "socks"
	inbound.CanSpliceCopy = 2
	inbound.User = &protocol.MemoryUser{
		Level: s.config.UserLevel,
	}
	if !proxy.IsRAWTransportWithoutSecurity(conn) {
		inbound.CanSpliceCopy = 3
	}

	switch network {
	case net.Network_TCP:
		firstbyte := make([]byte, 1)
		if n, err := conn.Read(firstbyte); n == 0 {
			if goerrors.Is(err, io.EOF) {
				errors.LogInfo(ctx, "Connection closed immediately, likely health check connection")
				return nil
			}
			return errors.New("failed to read from connection").Base(err)
		}
		if firstbyte[0] != 5 && firstbyte[0] != 4 { // Check if it is Socks5/4/4a
			errors.LogDebug(ctx, "Not Socks request, try to parse as HTTP request")
			return s.httpServer.ProcessWithFirstbyte(ctx, network, conn, dispatcher, firstbyte...)
		}
		return s.processTCP(ctx, conn, dispatcher, firstbyte)
	default:
		return errors.New("unknown network: ", network)
	}
}

func (s *Server) processTCP(ctx context.Context, conn stat.Connection, dispatcher routing.Dispatcher, firstbyte []byte) error {
	plcy := s.policy()
	if err := conn.SetReadDeadline(time.Now().Add(plcy.Timeouts.Handshake)); err != nil {
		errors.LogInfoInner(ctx, err, "failed to set deadline")
	}

	inbound := session.InboundFromContext(ctx)

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check the Base error: connection reset by peer vs i/o timeout tells you scanner vs timeout.
  2. If TLS was intended, enable TLS on the inbound (streamSettings.security) so the TLS layer consumes those bytes first.
  3. For timeout causes, raise policy.timeouts.handshake on the inbound.
  4. Expose the inbound only on loopback/LAN or front it with a firewall if scanner noise is constant.
Defensive patterns

Strategy: try-catch

Try / catch

if err := inbound.Process(ctx, conn, dispatcher); err != nil {
	if strings.Contains(err.Error(), "failed to read from connection") {
		return nil // treat as scanner/noise; don't fail the listener
	}
	log.Warn(err)
}

Prevention

When it happens

Trigger: conn.Read on a 1-byte buffer returns n == 0 with a connection-reset, i/o-timeout, or protocol error instead of io.EOF. Typical for port scanners that open and RST, or TLS clients connecting to a plaintext SOCKS port.

Common situations: Internet-exposed inbound port probed by mass scanners; TLS client (e.g. someone configured tls on the client but not the server); NAT/firewall sending RST; handshake timeout from the inbound policy exceeded.

Related errors


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