grpc/grpc-go · error
reading server HTTP response
Error message
reading server HTTP response: %v
What it means
Fires in doHTTPConnectHandshake (proxy.go:81) when http.ReadResponse cannot parse the proxy's reply to the CONNECT request. After writing CONNECT, gRPC reads the HTTP/1.1 response status line and headers from the proxy via a bufio.Reader; if the bytes received are not a valid HTTP response (or the read errors), this wraps the cause.
Solutions
- Confirm the proxy URL scheme matches what the proxy expects (https:// if the proxy itself requires TLS).
- Reproduce with curl --proxy <url> <target> to see the raw response; if curl fails similarly, the proxy is the issue.
- Increase the dial/read context deadline; a tight timeout can truncate the response read.
- Bypass the proxy temporarily to confirm the target is reachable, then fix the proxy configuration.
Example fix
// before: TLS-expecting proxy reached as plain HTTP
// HTTPS_PROXY=http://tls-proxy:443
// after
os.Setenv("HTTPS_PROXY", "https://tls-proxy:443")
// Go will dial TLS to the proxy, then issue CONNECT. Defensive patterns
Strategy: try-catch
Validate before calling
// Smoke-test the proxy with curl-like CONNECT before relying on it.
func probeProxyConnect(ctx context.Context, proxyURL, target string) error {
// open TCP to proxy, write CONNECT target, read status line
// return error if not HTTP/1.x
return nil
} Try / catch
conn, err := grpc.NewClient(target, opts...)
if err != nil && strings.Contains(err.Error(), "reading server HTTP response") {
// likely a scheme mismatch (http vs https) with the proxy
} Prevention
- Match the proxy URL scheme to the proxy's transport (http:// vs https://).
- Reproduce proxy issues with curl --proxy before debugging gRPC.
- Set a generous dial deadline.
When it happens
Trigger: The proxy sends non-HTTP bytes, closes the connection before a full response, or the read errors (reset, timeout, EOF). Examples: a proxy that speaks TLS-first but was reached as plain TCP and sends a ServerHello; a transparent proxy returning raw bytes; the connection dropping mid-response; context cancellation during the read.
Common situations: Pointing HTTPS_PROXY at a TLS-terminating proxy over plain TCP (scheme mismatch); a proxy that closes on unsupported methods; network interference (middleboxes, captive portals injecting HTML); cancelled dial context; proxy returning a malformed status line.
Related errors
- failed to do connect handshake, response
- failed to do connect handshake, status code
- failed to write the HTTP request
- ErrCodeEnhanceYourCalm
- gRPC requires a ResponseWriter supporting http.Flusher
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/20671c55a2943e52.
Report an issue: GitHub.
Appendix: source
Thrown at internal/transport/proxy.go:81
req := &http.Request{
Method: http.MethodConnect,
URL: &url.URL{Host: opts.ConnectAddr},
Header: map[string][]string{"User-Agent": {grpcUA}},
}
if user := opts.User; user != nil {
u := user.Username()
p, _ := user.Password()
req.Header.Add(proxyAuthHeaderKey, "Basic "+basicAuth(u, p))
}
if err := sendHTTPRequest(ctx, req, conn); err != nil {
return nil, fmt.Errorf("failed to write the HTTP request: %v", err)
}
r := bufio.NewReader(conn)
resp, err := http.ReadResponse(r, req)
if err != nil {
return nil, fmt.Errorf("reading server HTTP response: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
dump, err := httputil.DumpResponse(resp, true)
if err != nil {
return nil, fmt.Errorf("failed to do connect handshake, status code: %s", resp.Status)
}
return nil, fmt.Errorf("failed to do connect handshake, response: %q", dump)
}
// The buffer could contain extra bytes from the target server, so we can't
// discard it. However, in many cases where the server waits for the client
// to send the first message (e.g. when TLS is being used), the buffer will
// be empty, so we can avoid the overhead of reading through this buffer.
if r.Buffered() != 0 {
return &bufConn{Conn: conn, r: r}, nil
}
return conn, nil
}View on GitHub (pinned to 0c51461d27)