XTLS/Xray-core · error
inbound gateway not specified
Error message
inbound gateway not specified
What it means
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.
Source
Thrown at proxy/socks/server.go:105
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)
if inbound == nil || !inbound.Gateway.IsValid() {
return errors.New("inbound gateway not specified")
}
svrSession := &ServerSession{
config: s.config,
address: inbound.Gateway.Address,
port: inbound.Gateway.Port,
localAddress: net.IPAddress(conn.LocalAddr().(*net.TCPAddr).IP),
}
// 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)View on GitHub (pinned to 7d214f8b09)
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.
Example fix
// embedding code, before
ctx = session.ContextWithInbound(ctx, &session.Inbound{Source: src})
s.Process(ctx, conn, dispatcher)
// after
ctx = session.ContextWithInbound(ctx, &session.Inbound{
Source: src,
Gateway: net.DestinationFromAddr(conn.LocalAddr()), // required for BIND/UDP replies
})
s.Process(ctx, conn, dispatcher) Defensive patterns
Strategy: validation
Validate before calling
// when embedding: attach a valid gateway before Process
inbound := &session.Inbound{
Source: net.DestinationFromAddr(conn.RemoteAddr()),
Gateway: net.DestinationFromAddr(conn.LocalAddr()),
}
if !inbound.Gateway.IsValid() {
return errors.New("refusing to process without gateway")
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to read from connection
- unknown network: {network}
- failed to read request
- failed to dispatch request
- UDP associate with listen port failed
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/8ff02d4105ab8d5c.
Report an issue: GitHub.