ginuerzh/gost · error
resp.Status
Error message
resp.Status
What it means
In the http2 connector, after sending an HTTP/2 CONNECT request, any response status other than 200 causes the response body to be closed and an error carrying the raw HTTP status line (resp.Status, e.g. '403 Forbidden') to be returned. The library throws this because a non-200 means the proxy/tunnel refused to establish the HTTP/2 tunnel, so no usable connection exists.
Source
Thrown at http2.go:101
"Basic "+base64.StdEncoding.EncodeToString([]byte(u+":"+p)))
}
if Debug {
dump, _ := httputil.DumpRequest(req, false)
log.Log("[http2]", string(dump))
}
resp, err := cc.client.Do(req)
if err != nil {
cc.Close()
return nil, err
}
if Debug {
dump, _ := httputil.DumpResponse(resp, false)
log.Log("[http2]", string(dump))
}
if resp.StatusCode != http.StatusOK {
resp.Body.Close()
return nil, errors.New(resp.Status)
}
hc := &http2Conn{
r: resp.Body,
w: pw,
closed: make(chan struct{}),
}
hc.remoteAddr, _ = net.ResolveTCPAddr("tcp", address)
hc.localAddr, _ = net.ResolveTCPAddr("tcp", cc.addr)
return hc, nil
}
type http2Transporter struct {
clients map[string]*http.Client
clientMutex sync.Mutex
tlsConfig *tls.Config
}View on GitHub (pinned to a33fdbf4c9)
Solutions
- Read the status text in the returned error to identify the cause (401/407 → auth, 403 → forbidden, 5xx → proxy/server problem)
- Supply proxy credentials (auth node options / Proxy-Authorization) if 401/407
- Verify the destination is allowed by the proxy's ACL, or use an allowed target
- Test the proxy directly (curl --http2-prior-knowledge -X CONNECT or equivalent) to confirm it supports HTTP/2 CONNECT tunneling
Example fix
// before
c, err := h2Connector.Connect(ctx, cc, "forbidden-host:443")
if err != nil { log.Fatal(err) } // '403 Forbidden' with no context
// after
c, err := h2Connector.Connect(ctx, cc, address)
if err != nil {
log.Printf("http2 tunnel to %s rejected: %v", address, err) // status line reveals cause
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate proxy reachability/auth before tunneling
resp, err := httpclient.Get("https://" + proxyHost + "/")
if err == nil && (resp.StatusCode == 401 || resp.StatusCode == 407) {
return nil, errors.New("proxy credentials missing or invalid")
} Type guard
func isConnectRejected(err error) bool {
// error text is the raw HTTP status line, e.g. '403 Forbidden'
return err != nil && regexp.MustCompile(`^\d{3} `).MatchString(err.Error())
} Try / catch
c, err := connector.Connect(ctx, cc, address)
if err != nil {
if isConnectRejected(err) {
switch {
case strings.HasPrefix(err.Error(), "401"), strings.HasPrefix(err.Error(), "407"):
return nil, fmt.Errorf("proxy auth required: %w", err)
default:
return nil, fmt.Errorf("tunnel to %s rejected: %w", address, err)
}
}
return nil, err
} Prevention
- Configure proxy credentials before dialing through authenticated proxies
- Verify the destination is permitted by the proxy's ACL
- Test the HTTP/2 proxy supports CONNECT with curl before deploying
- Only retry on transient statuses (429/503); fail fast on 4xx
When it happens
Trigger: Dialing through an HTTP/2 proxy whose response to the CONNECT request is not 200 OK — auth rejected (401/407), target forbidden (403), target unreachable (404/502), rate limits (429), or server errors (500/502/503).
Common situations: Proxy requiring credentials that weren't supplied; proxy ACLs blocking the destination; the remote host rejecting CONNECT tunneling entirely; expired proxy sessions/tokens; misconfigured proxy upstream.
Related errors
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/21a1cf2f7f7df6e9.
Report an issue: GitHub.