{"record":{"id":"8ff02d4105ab8d5c","repo":"XTLS/Xray-core","slug":"inbound-gateway-not-specified","errorCode":null,"errorMessage":"inbound gateway not specified","messagePattern":"inbound gateway not specified","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/socks/server.go","lineNumber":105,"sourceCode":"\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)\n\tif inbound == nil || !inbound.Gateway.IsValid() {\n\t\treturn errors.New(\"inbound gateway not specified\")\n\t}\n\n\tsvrSession := &ServerSession{\n\t\tconfig:       s.config,\n\t\taddress:      inbound.Gateway.Address,\n\t\tport:         inbound.Gateway.Port,\n\t\tlocalAddress: net.IPAddress(conn.LocalAddr().(*net.TCPAddr).IP),\n\t}\n\n\t// Firstbyte is for forwarded conn from SOCKS inbound\n\t// Because it needs first byte to choose protocol\n\t// We need to add it back\n\treader := &buf.BufferedReader{\n\t\tReader: buf.NewReader(conn),\n\t\tBuffer: buf.MultiBuffer{buf.FromBytes(firstbyte)},\n\t}\n\trequest, tempUDPConn, err := svrSession.Handshake(reader, conn)\n\tdefer common.CloseIfExists(tempUDPConn)","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/socks/server.go#L87-L123","documentation":"Thrown by the SOCKS inbound's processTCP when the session's inbound gateway (the address/port this inbound serves, attached by the listener) is missing or invalid. The gateway is needed to build the ServerSession that answers SOCKS5 BIND/UDP ASSOCIATE with a reachable bind address.","triggerScenarios":"session.InboundFromContext(ctx) returns nil or an Inbound whose Gateway.IsValid() is false — the context was not populated with a gateway by a standard internet listener, typically when the handler is embedded or driven by non-standard code rather than the normal inbound manager.","commonSituations":"Third-party code embedding Xray-core and dispatching connections manually without setting inbound.Gateway; a custom transport/launcher that skips the standard listener initialization; version mismatch after an API change in session plumbing.","solutions":["Route connections through the standard inbound handler manager (core.RegisterInboundHandler + normal listener) so Gateway is populated.","If embedding, set session.Inbound{Gateway: net.DestinationFromAddr(conn.LocalAddr())} into the context before calling Process.","Align your fork/vendor copy with the current core version — older code may omit gateway initialization."],"exampleFix":"// embedding code, before\nctx = session.ContextWithInbound(ctx, &session.Inbound{Source: src})\ns.Process(ctx, conn, dispatcher)\n\n// after\nctx = session.ContextWithInbound(ctx, &session.Inbound{\n\tSource:  src,\n\tGateway: net.DestinationFromAddr(conn.LocalAddr()), // required for BIND/UDP replies\n})\ns.Process(ctx, conn, dispatcher)","handlingStrategy":"validation","validationCode":"// when embedding: attach a valid gateway before Process\ninbound := &session.Inbound{\n\tSource:  net.DestinationFromAddr(conn.RemoteAddr()),\n\tGateway: net.DestinationFromAddr(conn.LocalAddr()),\n}\nif !inbound.Gateway.IsValid() {\n\treturn errors.New(\"refusing to process without gateway\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never call inbound handlers outside the standard listener path without session setup.","Pin your core version in go.mod when embedding to avoid session API drift.","Unit-test embedded dispatch paths with a fake dispatcher."],"tags":["socks","inbound","session","gateway","embedding"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}