ginuerzh/gost · error
%s unsupported
Error message
%s unsupported
What it means
The SNI connector's ConnectContext (sni.go:41) rejects any network type other than TCP. SNI (Server Name Indication) tunneling is implemented over TCP streams only, so passing "udp", "udp4", or "udp6" returns this error immediately without attempting a connection.
Source
Thrown at sni.go:41
)
type sniConnector struct {
host string
}
// SNIConnector creates a Connector for SNI proxy client.
func SNIConnector(host string) Connector {
return &sniConnector{host: host}
}
func (c *sniConnector) Connect(conn net.Conn, address string, options ...ConnectOption) (net.Conn, error) {
return c.ConnectContext(context.Background(), conn, "tcp", address, options...)
}
func (c *sniConnector) ConnectContext(ctx context.Context, conn net.Conn, network, address string, options ...ConnectOption) (net.Conn, error) {
switch network {
case "udp", "udp4", "udp6":
return nil, fmt.Errorf("%s unsupported", network)
}
return &sniClientConn{addr: address, host: c.host, Conn: conn}, nil
}
type sniHandler struct {
options *HandlerOptions
}
// SNIHandler creates a server Handler for SNI proxy server.
func SNIHandler(opts ...HandlerOption) Handler {
h := &sniHandler{}
h.Init(opts...)
return h
}
func (h *sniHandler) Init(options ...HandlerOption) {View on GitHub (pinned to a33fdbf4c9)
Solutions
- Pass "tcp" (or "tcp4"/"tcp6") as the network argument when using the SNI connector
- Remove the SNI connector from any path that must carry UDP traffic and use a UDP-capable connector instead
- Normalize/validate the network string at the call site before dialing so it cannot be a UDP variant
Example fix
// before conn, err := connector.ConnectContext(ctx, rawConn, "udp", "example.com:443") // %s unsupported // after conn, err := connector.ConnectContext(ctx, rawConn, "tcp", "example.com:443")
Defensive patterns
Strategy: validation
Validate before calling
func validateSNINetwork(network string) error {
switch network {
case "", "tcp", "tcp4", "tcp6":
return nil
default:
return fmt.Errorf("SNI connector requires TCP, got %q", network)
}
}
// call before ConnectContext
if err := validateSNINetwork(network); err != nil { return err } Type guard
func isTCPNetwork(network string) bool {
return network == "" || network == "tcp" || network == "tcp4" || network == "tcp6"
} Try / catch
conn, err := sniConnector.ConnectContext(ctx, rawConn, network, addr)
if err != nil {
if strings.Contains(err.Error(), " unsupported") {
return fmt.Errorf("SNI does not support %q; use tcp or a UDP-capable connector", network)
}
return err
} Prevention
- Only route TCP dials through the SNI connector
- Normalize network strings (lowercase, default to "tcp") before dialing
- Audit proxy-chain configuration so UDP hops never land on the SNI connector
- If you need UDP, pick a connector that supports it instead of forcing SNI
When it happens
Trigger: Calling sniConnector.ConnectContext (directly or via the convenience Connect wrapper) with network set to "udp", "udp4", or "udp6" instead of "tcp"/"tcp4"/"tcp6" or an empty string.
Common situations: Configuring a proxy chain where a UDP-based protocol is routed through the SNI connector; code that iterates network types generically ("tcp", "udp") and hits the SNI hop; typos like "UDP" capitalized elsewhere that fall through to a UDP default upstream; misunderstanding SNI as a general-purpose transport.
Related errors
- %s unsupported
- accpet on closed listener
- read from closed connection
- connection is closed
- %s unsupported
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/73162f0254aaa756.
Report an issue: GitHub.