geektutu/7days-golang · error

server returned: %v

Error message

server returned: %v

What it means

The httpGetter peer client checks the HTTP status of the response from a remote gee-cache node and rejects anything other than 200 OK, wrapping the status line (e.g. "500 Internal Server Error") in this error. This happens when the remote node's ServeHTTP handler returned an error status — typically because that node failed to load the value, hit its own 'key is required' error, or experienced an internal failure. The error propagates back through GetGroup/Get to the original caller.

Source

Thrown at gee-cache/day5-multi-nodes/geecache/http.go:117

type httpGetter struct {
	baseURL string
}

func (h *httpGetter) Get(group string, key string) ([]byte, error) {
	u := fmt.Sprintf(
		"%v%v/%v",
		h.baseURL,
		url.QueryEscape(group),
		url.QueryEscape(key),
	)
	res, err := http.Get(u)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	if res.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("server returned: %v", res.Status)
	}

	bytes, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, fmt.Errorf("reading response body: %v", err)
	}

	return bytes, nil
}

var _ PeerGetter = (*httpGetter)(nil)

View on GitHub (pinned to cf36443821)

Solutions

  1. Inspect the wrapped status text in the error to identify which peer and which status; check that peer's logs for the underlying failure
  2. Verify the peer's address and basePath registered in gee-cache's peers/scheduler match the actually running server
  3. Ensure the peer process is healthy (restart it, check its loader dependencies like DB/etcd)
  4. Add retry/failover at the caller if peers can be transiently unavailable

Example fix

// before
v, err := group.Get(key) // "server returned: 404 Not Found" on bad basePath
// after
// register peers with the exact path the server serves:
peers.Set(baseURL + "/_geecache/") // server must mount httpPool.Handler() on the same basePath
Defensive patterns

Strategy: retry

Validate before calling

// health-check peers before relying on them
resp, err := http.Get(peerURL + basePath + "/_health/")
if err != nil || resp.StatusCode != http.StatusOK {
    return errors.New("peer unavailable: " + peerURL)
}

Try / catch

v, err := group.Get(key)
if err != nil {
    var retriable = strings.Contains(err.Error(), "server returned: 5")
    if retriable {
        time.Sleep(100 * time.Millisecond)
        return group.Get(key) // retry, or fall back to local loader
    }
    return err
}

Prevention

When it happens

Trigger: Calling group.Get(key) where the consistent-hash ring routes the key to a peer node whose HTTP endpoint answers with 4xx/5xx; peer server crashed mid-request and a proxy returned 502/503; wrong base URL configured in the peer pool causing 404 Not Found.

Common situations: A peer node not yet started or listening on a different port than registered; a reverse proxy in front of the node returning 502; the peer's handler returning 500 because its loader/DB failed; mistyped basePath so requests 404.

Related errors


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