ginuerzh/gost · error

%s

Error message

%s

What it means

The HTTP CONNECT tunnel was established at the transport level, but the proxy answered with a non-200 status code. The connector surfaces the raw HTTP status line (e.g. "403 Forbidden", "502 Bad Gateway") as the error.

Solutions

  1. Read resp.Status in the error to identify the code and act on it (401/407 → add credentials, 403 → fix proxy ACL, 5xx → check upstream).
  2. Add correct proxy authentication (user:pass@host in the node address or Proxy-Authorization header).
  3. Verify the target host:port is allowed by the proxy's policy; try a different target/port.
  4. Test the proxy with curl -x proxy -I to confirm it accepts CONNECT independently of this library.

Example fix

// before
node = "http://proxy.corp:3128?tunnel=direct" // proxy requires auth
// after
node = "http://user:pass@proxy.corp:3128"
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check proxy CONNECT support
cmd := exec.Command("curl", "-x", proxyURL, "-I", "https://target:443", "--max-time", "10")
if err := cmd.Run(); err != nil { log.Println("proxy CONNECT pre-check failed") }

Try / catch

conn, err := connector.Connect(conn, "tcp", addr)
if err != nil {
    if strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "407") {
        return fmt.Errorf("proxy auth required: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: ConnectContext receives resp.StatusCode != http.StatusOK after sending the HTTP CONNECT request — proxy refuses the CONNECT (auth missing/wrong, target blocked, proxy overloaded, upstream failure).

Common situations: Corporate proxies rejecting CONNECT to non-443 ports; proxy requiring Proxy-Authorization credentials; upstream target unreachable so proxy returns 502/504; ACLs on the proxy denying the destination.

Related errors


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

Appendix: source

Thrown at http.go:102

	}

	if Debug {
		dump, _ := httputil.DumpRequest(req, false)
		log.Log(string(dump))
	}

	resp, err := http.ReadResponse(bufio.NewReader(conn), req)
	if err != nil {
		return nil, err
	}

	if Debug {
		dump, _ := httputil.DumpResponse(resp, false)
		log.Log(string(dump))
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("%s", resp.Status)
	}

	return conn, nil
}

type httpHandler struct {
	options *HandlerOptions
}

// HTTPHandler creates a server Handler for HTTP proxy server.
func HTTPHandler(opts ...HandlerOption) Handler {
	h := &httpHandler{}
	h.Init(opts...)
	return h
}

func (h *httpHandler) Init(options ...HandlerOption) {
	if h.options == nil {

View on GitHub (pinned to a33fdbf4c9)