ginuerzh/gost · error

%s unsupported

Error message

%s unsupported

What it means

Formed by http2Connector.ConnectContext with the requested network substituted for %s when that network is not TCP — HTTP/2 proxying here only supports stream-oriented TCP connections, so values like udp are rejected up front. A caller-misuse guard, not a runtime proxy failure.

Source

Thrown at http2.go:43

type http2Connector struct {
	User *url.Userinfo
}

// HTTP2Connector creates a Connector for HTTP2 proxy client.
// It accepts an optional auth info for HTTP Basic Authentication.
func HTTP2Connector(user *url.Userinfo) Connector {
	return &http2Connector{User: user}
}

func (c *http2Connector) Connect(conn net.Conn, address string, options ...ConnectOption) (net.Conn, error) {
	return c.ConnectContext(context.Background(), conn, "tcp", address, options...)
}

func (c *http2Connector) 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)
	}

	opts := &ConnectOptions{}
	for _, option := range options {
		option(opts)
	}
	ua := opts.UserAgent
	if ua == "" {
		ua = DefaultUserAgent
	}

	cc, ok := conn.(*http2ClientConn)
	if !ok {
		return nil, errors.New("wrong connection type")
	}

	pr, pw := io.Pipe()
	req := &http.Request{

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Use "tcp" as the network for http2 nodes.
  2. For UDP, pick a UDP-capable node type (socks5, relay, ss, ku, etc.) or tunnel UDP over a TCP-based transport that supports it.
  3. Separate TCP and UDP forwarder configs so the http2 scheme is never selected for UDP traffic.

Example fix

// before
forwarder: udp://:53 -> http2://relay:443
// after
forwarder: udp://:53 -> relay+ws://relay:443
Defensive patterns

Strategy: validation

Validate before calling

if network != "tcp" {
    return fmt.Errorf("http2 connector supports tcp only, got %s", network)
}
_ = h2Connector.Connect(conn, network, addr)

Type guard

func isTCPOnly(scheme string) bool { return scheme == "http" || scheme == "http2" }

Prevention

When it happens

Trigger: Calling (http2Connector).Connect/ConnectContext with network "udp"/"udp4"/"udp6", e.g. wiring an http2 hop into a UDP forwarder or relay chain.

Common situations: Configuring UDP-over-HTTP2 tunnels by mistake; reusing the same node definition for both TCP and UDP forwarding; generic forwarding code propagating the listener's network type into the dialer.

Related errors


AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02). Data as JSON: /api/errors/f6fd004868a06e6a. Report an issue: GitHub.