{"record":{"id":"e4bd20679fca1ea4","repo":"XTLS/Xray-core","slug":"failed-to-read-from-connection","errorCode":null,"errorMessage":"failed to read from connection","messagePattern":"failed to read from connection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/socks/server.go","lineNumber":85,"sourceCode":"\tinbound := session.InboundFromContext(ctx)\n\tinbound.Name = \"socks\"\n\tinbound.CanSpliceCopy = 2\n\tinbound.User = &protocol.MemoryUser{\n\t\tLevel: s.config.UserLevel,\n\t}\n\tif !proxy.IsRAWTransportWithoutSecurity(conn) {\n\t\tinbound.CanSpliceCopy = 3\n\t}\n\n\tswitch network {\n\tcase net.Network_TCP:\n\t\tfirstbyte := make([]byte, 1)\n\t\tif n, err := conn.Read(firstbyte); n == 0 {\n\t\t\tif goerrors.Is(err, io.EOF) {\n\t\t\t\terrors.LogInfo(ctx, \"Connection closed immediately, likely health check connection\")\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn errors.New(\"failed to read from connection\").Base(err)\n\t\t}\n\t\tif firstbyte[0] != 5 && firstbyte[0] != 4 { // Check if it is Socks5/4/4a\n\t\t\terrors.LogDebug(ctx, \"Not Socks request, try to parse as HTTP request\")\n\t\t\treturn s.httpServer.ProcessWithFirstbyte(ctx, network, conn, dispatcher, firstbyte...)\n\t\t}\n\t\treturn s.processTCP(ctx, conn, dispatcher, firstbyte)\n\tdefault:\n\t\treturn errors.New(\"unknown network: \", network)\n\t}\n}\n\nfunc (s *Server) processTCP(ctx context.Context, conn stat.Connection, dispatcher routing.Dispatcher, firstbyte []byte) error {\n\tplcy := s.policy()\n\tif err := conn.SetReadDeadline(time.Now().Add(plcy.Timeouts.Handshake)); err != nil {\n\t\terrors.LogInfoInner(ctx, err, \"failed to set deadline\")\n\t}\n\n\tinbound := session.InboundFromContext(ctx)","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/socks/server.go#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the Base error: connection reset by peer vs i/o timeout tells you scanner vs timeout.","If TLS was intended, enable TLS on the inbound (streamSettings.security) so the TLS layer consumes those bytes first.","For timeout causes, raise policy.timeouts.handshake on the inbound.","Expose the inbound only on loopback/LAN or front it with a firewall if scanner noise is constant."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := inbound.Process(ctx, conn, dispatcher); err != nil {\n\tif strings.Contains(err.Error(), \"failed to read from connection\") {\n\t\treturn nil // treat as scanner/noise; don't fail the listener\n\t}\n\tlog.Warn(err)\n}","preventionTips":["Front public inbounds with a firewall or fail2ban for scan noise.","Match TLS settings on both ends to avoid protocol-byte collisions.","Set sane handshake timeouts to shed dead peers quickly."],"tags":["socks","inbound","tcp","read-error","first-byte"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}