ginuerzh/gost · error

%s unsupported

Error message

%s unsupported

What it means

The shadowsocks connector (shadowConnector) only supports TCP-based networks. ConnectContext rejects any network argument of "udp", "udp4", or "udp6" with this '<network> unsupported' error, because the shadow stream connector cannot carry UDP associations.

Source

Thrown at ss.go:47

	cipher core.Cipher
}

// ShadowConnector creates a Connector for shadowsocks proxy client.
// It accepts an optional cipher info for shadowsocks data encryption/decryption.
func ShadowConnector(info *url.Userinfo) Connector {
	return &shadowConnector{
		cipher: initShadowCipher(info),
	}
}

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

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

	timeout := opts.Timeout
	if timeout <= 0 {
		timeout = ConnectTimeout
	}

	socksAddr, err := gosocks5.NewAddr(address)
	if err != nil {
		return nil, err
	}
	rawaddr := sPool.Get().([]byte)
	defer sPool.Put(rawaddr)

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Use network "tcp", "tcp4", or "tcp6" with shadowConnector
  2. For UDP traffic, use the dedicated UDP connector (shadowUDPConnector / UDP listener path) instead
  3. Validate the network parameter at config load time and fail fast with a clear message

Example fix

// before
conn, err := connector.Connect(context.Background(), netConn, "udp", addr)
// after
conn, err := connector.Connect(context.Background(), netConn, "tcp", addr)
Defensive patterns

Strategy: validation

Validate before calling

if strings.HasPrefix(network, "udp") {
    return errors.New("shadowConnector requires a tcp network; use the UDP connector for udp")
}

Type guard

func isTCPNetwork(n string) bool {
    switch n { case "tcp", "tcp4", "tcp6": return true }
    return false
}

Try / catch

conn, err := connector.Connect(ctx, netConn, network, addr)
if err != nil && strings.HasSuffix(err.Error(), "unsupported") {
    return fmt.Errorf("wrong connector for network %q: %w", network, err)
}

Prevention

When it happens

Trigger: Calling shadowConnector.Connect / ConnectContext with network set to "udp", "udp4", or "udp6" instead of "tcp" (or a TCP alias).

Common situations: Passing a user- or config-supplied network string straight into the dialer; wiring a UDP client through a TCP shadow connector instead of using the dedicated shadow UDP connector (shadowUDPConnector).

Related errors


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