ginuerzh/gost · error
wrong connection type
Error message
wrong connection type
What it means
http2 connector's ConnectContext asserts that the passed connection is a *http2ClientConn; if the type assertion fails it returns 'wrong connection type'. This connector only knows how to issue HTTP/2 CONNECT requests over its own client-connection type, so passing any other net.Conn (e.g. a plain TCP conn or an http2Conn) is rejected up front. It is a programming/wiring error, not a network failure.
Source
Thrown at http2.go:57
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{
Method: http.MethodConnect,
URL: &url.URL{Scheme: "https", Host: cc.addr},
Header: make(http.Header),
Proto: "HTTP/2.0",
ProtoMajor: 2,
ProtoMinor: 0,
Body: pr,
Host: address,
ContentLength: -1,
}
req.Header.Set("User-Agent", ua)
user := opts.User
if user == nil {View on GitHub (pinned to a33fdbf4c9)
Solutions
- Ensure the conn passed to Connect comes from the same http2 connector's Dial (a *http2ClientConn)
- Fix chain wiring so the http2 node uses the http2 dialer/transport, not a plain TCP dialer
- Check node/chain configuration (scheme http2 vs http/tcp) so connector and transport match
- Log the concrete type of the conn (%T) at the call site to find where the wrong conn originates
Example fix
// before
conn, _ := net.Dial("tcp", addr)
c, err := h2Connector.Connect(ctx, conn, address) // wrong connection type
// after
clientConn, err := h2Connector.Dial(ctx, address, opts) // produces *http2ClientConn
c, err := h2Connector.Connect(ctx, clientConn, address) Defensive patterns
Strategy: type-guard
Validate before calling
// Before calling Connect, ensure the conn came from the same http2 dialer
if _, ok := conn.(*http2ClientConn); !ok {
return fmt.Errorf("http2 Connect requires *http2ClientConn, got %T", conn)
} Type guard
func isHTTP2ClientConn(c net.Conn) (*http2ClientConn, bool) {
cc, ok := c.(*http2ClientConn)
return cc, ok
} Try / catch
c, err := connector.Connect(ctx, conn, address)
if err != nil {
if err.Error() == "wrong connection type" {
return nil, fmt.Errorf("wiring bug: conn is %T, expected *http2ClientConn", conn)
}
return nil, err
} Prevention
- Always obtain the conn from the same connector family's Dial before Connect
- Keep chain configs consistent (http2 node ↔ http2 dialer)
- Log %T of connections at chain hand-off points during development
When it happens
Trigger: Calling gost's http2 Connect(ctx, conn, address) with a connection that was not produced by the http2 connector's own Dial (i.e. not a *http2ClientConn) — for example reusing a generic dialer's conn or mixing up http and http2 connector instances.
Common situations: Building custom chains where the wrong connector gets paired with a transport's connection; refactors that swap http2 dialer for tcp/relay but keep the http2 connector; passing an http2Conn (server-side stream) into a client Connect call.
Related errors
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/23d717d487cf51ba.
Report an issue: GitHub.