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.

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)

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.