geektutu/7days-golang · error

unexpected HTTP response:

Error message

unexpected HTTP response: 

What it means

NewHTTPClient dials the server using the HTTP CONNECT protocol and expects the server to reply with the exact status line "200 Connected to Gee RPC" before the connection is switched to the RPC protocol. If the server's response is a valid HTTP response with any other status, this error is thrown so the caller knows the handshake failed.

Source

Thrown at gee-rpc/day5-http-debug/client.go:295

}

// Dial connects to an RPC server at the specified network address
func Dial(network, address string, opts ...*Option) (*Client, error) {
	return dialTimeout(NewClient, network, address, opts...)
}

// NewHTTPClient new a Client instance via HTTP as transport protocol
func NewHTTPClient(conn net.Conn, opt *Option) (*Client, error) {
	_, _ = io.WriteString(conn, fmt.Sprintf("CONNECT %s HTTP/1.0\n\n", defaultRPCPath))

	// Require successful HTTP response
	// before switching to RPC protocol.
	resp, err := http.ReadResponse(bufio.NewReader(conn), &http.Request{Method: "CONNECT"})
	if err == nil && resp.Status == connected {
		return NewClient(conn, opt)
	}
	if err == nil {
		err = errors.New("unexpected HTTP response: " + resp.Status)
	}
	return nil, err
}

// DialHTTP connects to an HTTP RPC server at the specified network address
// listening on the default HTTP RPC path.
func DialHTTP(network, address string, opts ...*Option) (*Client, error) {
	return dialTimeout(NewHTTPClient, network, address, opts...)
}

// XDial calls different functions to connect to a RPC server
// according the first parameter rpcAddr.
// rpcAddr is a general format (protocol@addr) to represent a rpc server
// eg, http@10.0.0.1:7001, tcp@10.0.0.1:9999, unix@/tmp/geerpc.sock
func XDial(rpcAddr string, opts ...*Option) (*Client, error) {
	parts := strings.Split(rpcAddr, "@")
	if len(parts) != 2 {
		return nil, fmt.Errorf("rpc client err: wrong format '%s', expect protocol@addr", rpcAddr)

View on GitHub (pinned to cf36443821)

Solutions

  1. Start the server in HTTP mode (NewHTTPServer / http.Handle with gee-rpc's HTTPCodecConn or XPrt-based handler) so it answers CONNECT with the expected status
  2. Verify the address/port in DialHTTP points at the RPC server, not another HTTP service or proxy
  3. Bypass or reconfigure proxies on that port so the CONNECT request reaches the gee-rpc server directly
  4. Check the server log for the exact resp.Status to confirm who sent the unexpected response

Example fix

// before
conn, err := net.Dial("tcp", addr) // server is a plain TCP rpc server
client, err := geeprc.NewHTTPClient(conn)
// after
lis, _ := net.Listen("tcp", addr) // on server side, run HTTP-mode server
srv := geeprc.NewHTTPServer()
http.Handle("/_geerpc_", srv)
// then connect with NewHTTPClient / DialHTTP to the correct address
Defensive patterns

Strategy: fallback

Validate before calling

addr := "localhost:9999"
if u, err := url.Parse(addr); err == nil && u.Scheme != "" {
    addr = u.Host // ensure raw host:port, not a URL
}

Try / catch

client, err := geeprc.DialHTTP("tcp", addr)
if err != nil {
    if strings.Contains(err.Error(), "unexpected HTTP response") {
        // retry with plain NewClient (non-HTTP mode) or fail fast with a clear message
        return fmt.Errorf("%s is not an HTTP-mode rpc server: %w", addr, err)
    }
    return err
}

Prevention

When it happens

Trigger: DialHTTP/NewHTTPClient is pointed at: (1) an endpoint that is not a gee-rpc HTTP-mode server, (2) a server built with the plain (non-HTTP) NewServer/Listen instead of NewHTTPServer/HTTP registry, or (3) a proxy/load balancer that answers CONNECT with its own status line.

Common situations: Connecting to a regular TCP gee-rpc port with DialHTTP, hitting the wrong port behind an nginx/HAProxy that intercepts the request, or a misconfigured service registry pointing to an HTTP health endpoint instead of the RPC endpoint.

Related errors


AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03). Data as JSON: /api/errors/925d2612c4d32777. Report an issue: GitHub.