valyala/fasthttp · error

could not connect to proxy addr: %s status code: %d

Error message

could not connect to proxy addr: %s status code: %d

What it means

fasthttpproxy's httpProxyDial sends a CONNECT request through an HTTP proxy and expects a '200 Connection established' response. When the proxy replies with any non-200 status code, the connection is closed and this error is returned with the proxy address and the actual status code, indicating the proxy refused the tunnel.

Source

Thrown at fasthttpproxy/dialer.go:270

	if auth != "" {
		req += "Proxy-Authorization: Basic " + auth + "\r\n"
	}
	req += "\r\n"
	_, err = conn.Write([]byte(req))
	if err != nil {
		_ = conn.Close()
		return nil, err
	}
	res := fasthttp.AcquireResponse()
	defer fasthttp.ReleaseResponse(res)
	res.SkipBody = true
	if err = res.Read(bufio.NewReaderSize(conn, 1024)); err != nil {
		_ = conn.Close()
		return nil, err
	}
	if res.Header.StatusCode() != 200 {
		_ = conn.Close()
		err = fmt.Errorf("could not connect to proxy addr: %s status code: %d", proxyAddr, res.Header.StatusCode())
		return nil, err
	}
	return conn, err
}

// Cache authentication information for HTTP proxies.
type proxyInfo struct {
	auth string
	addr string
}

func addrAndAuth(pu *url.URL, authCache *sync.Map) (proxyAddr, auth string) {
	if pu.User == nil {
		proxyAddr = pu.Host + pu.Path
		return proxyAddr, auth
	}
	if authCache != nil {
		if v, ok := authCache.Load(pu); ok {

View on GitHub (pinned to c96f600972)

Solutions

  1. Check the status code in the message: 407 means add proxy authentication (use FasthttpHTTPDialerProxy with an auth URL like http://user:pass@host:port), 403/405 usually means the host is blocked or the proxy does not allow CONNECT
  2. Verify the proxy address actually speaks HTTP CONNECT (not SOCKS — use fasthttpproxy's SOCKS dialer for socks5:// proxies)
  3. Sanitize/validate the target host string to exclude CR/LF and spaces before dialing
  4. Test the same request with curl -x proxy:port to confirm the proxy policy outside your code

Example fix

// before
d := fasthttpproxy.FasthttpHTTPDialer("proxy.corp.local:3128")
// after — include credentials so the proxy does not answer 407
d := fasthttpproxy.FasthttpHTTPDialerTimeout("user:pass@proxy.corp.local:3128", 10*time.Second)
Defensive patterns

Strategy: try-catch

Validate before calling

if strings.ContainsAny(targetAddr, "\r\n ") {
    return fmt.Errorf("invalid target address: %q", targetAddr)
}

Type guard

func isPrintableHost(addr string) bool {
    for _, r := range addr {
        if r <= 0x20 || r == 0x7f { return false }
    }
    return len(addr) > 0
}

Try / catch

conn, err := dialer.Dial(addr)
if err != nil {
    var perr *fasthttpproxy.ProxyError // if wrapped
    if strings.Contains(err.Error(), "status code: 407") {
        // refresh proxy credentials and retry once
    }
    return fmt.Errorf("proxy tunnel rejected: %w", err)
}

Prevention

When it happens

Trigger: Calling fasthttpproxy.FasthttpHTTPDialer / FasthttpHTTPDialerTimeout (or the proxy transport built on it) when the target host requires the CONNECT method and the proxy responds 403/407/502 etc. — e.g. proxy requires authentication, blocks the destination, or is not actually an HTTP proxy. The test TestHTTPProxyDialRejectsTargetAddrContainingNewlines shows it also fires when header injection via the target address is rejected.

Common situations: Corporate proxies rejecting CONNECT to non-whitelisted hosts; missing Proxy-Authorization for a proxy that demands credentials; pointing the dialer at a SOCKS or plain-HTTP endpoint that answers 4xx/5xx to CONNECT; a target address containing '\r\n' being rejected by the proxy.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/e5e264a1226e4f21. Report an issue: GitHub.