{"record":{"id":"21a1cf2f7f7df6e9","repo":"ginuerzh/gost","slug":"resp-status","errorCode":null,"errorMessage":"resp.Status","messagePattern":"resp\\.Status","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"http2.go","lineNumber":101,"sourceCode":"\t\t\t\"Basic \"+base64.StdEncoding.EncodeToString([]byte(u+\":\"+p)))\n\t}\n\tif Debug {\n\t\tdump, _ := httputil.DumpRequest(req, false)\n\t\tlog.Log(\"[http2]\", string(dump))\n\t}\n\tresp, err := cc.client.Do(req)\n\tif err != nil {\n\t\tcc.Close()\n\t\treturn nil, err\n\t}\n\tif Debug {\n\t\tdump, _ := httputil.DumpResponse(resp, false)\n\t\tlog.Log(\"[http2]\", string(dump))\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tresp.Body.Close()\n\t\treturn nil, errors.New(resp.Status)\n\t}\n\thc := &http2Conn{\n\t\tr:      resp.Body,\n\t\tw:      pw,\n\t\tclosed: make(chan struct{}),\n\t}\n\n\thc.remoteAddr, _ = net.ResolveTCPAddr(\"tcp\", address)\n\thc.localAddr, _ = net.ResolveTCPAddr(\"tcp\", cc.addr)\n\n\treturn hc, nil\n}\n\ntype http2Transporter struct {\n\tclients     map[string]*http.Client\n\tclientMutex sync.Mutex\n\ttlsConfig   *tls.Config\n}","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/http2.go#L83-L119","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nc, err := h2Connector.Connect(ctx, cc, \"forbidden-host:443\")\nif err != nil { log.Fatal(err) } // '403 Forbidden' with no context\n// after\nc, err := h2Connector.Connect(ctx, cc, address)\nif err != nil {\n  log.Printf(\"http2 tunnel to %s rejected: %v\", address, err) // status line reveals cause\n  return err\n}","handlingStrategy":"try-catch","validationCode":"// Pre-validate proxy reachability/auth before tunneling\nresp, err := httpclient.Get(\"https://\" + proxyHost + \"/\")\nif err == nil && (resp.StatusCode == 401 || resp.StatusCode == 407) {\n    return nil, errors.New(\"proxy credentials missing or invalid\")\n}","typeGuard":"func isConnectRejected(err error) bool {\n    // error text is the raw HTTP status line, e.g. '403 Forbidden'\n    return err != nil && regexp.MustCompile(`^\\d{3} `).MatchString(err.Error())\n}","tryCatchPattern":"c, err := connector.Connect(ctx, cc, address)\nif err != nil {\n    if isConnectRejected(err) {\n        switch {\n        case strings.HasPrefix(err.Error(), \"401\"), strings.HasPrefix(err.Error(), \"407\"):\n            return nil, fmt.Errorf(\"proxy auth required: %w\", err)\n        default:\n            return nil, fmt.Errorf(\"tunnel to %s rejected: %w\", address, err)\n        }\n    }\n    return nil, err\n}","preventionTips":["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"],"tags":["http2","http-status","proxy","tunnel","connect"],"backgroundTag":"http-connect-rejected","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}