geektutu/7days-golang · error

server returned: %v

Error message

server returned: %v

What it means

Same peer-status check as day5, in the day6-single-flight build: httpGetter.Get returns "server returned: %v" when a peer node responds with a non-200 status. In this version the error surfaces from within the single-flight group, so all callers waiting on the same key receive the same error for one failed peer request.

Source

Thrown at gee-cache/day6-single-flight/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. Read the status from the error and inspect the peer node's logs
  2. Fix peer registration (address + basePath) to match the running server
  3. Restart or repair the unhealthy peer; verify its loader dependencies
  4. Consider per-call fallback to the local loader when peer fetch fails

Example fix

// before
// peer fails -> all single-flight waiters get "server returned: 500"
v, err := g.Get(key)
// after
v, err := g.Get(key)
if err != nil {
    log.Printf("peer fetch failed for %q: %v, loading locally", key, err)
    return g.loader(key) // fallback to local source
}
Defensive patterns

Strategy: fallback

Validate before calling

// verify peer reachability before the ring routes to it
conn, err := net.DialTimeout("tcp", peerHost, 2*time.Second)
if err != nil {
    log.Printf("peer %s unreachable, excluding from ring", peerHost)
}

Try / catch

v, err := group.Get(key)
if err != nil && strings.Contains(err.Error(), "server returned:") {
    log.Printf("peer error: %v; falling back to local loader", err)
    return g.reloadFromSource(key) // local Getter instead of failing all waiters
}

Prevention

When it happens

Trigger: group.Get routed via consistent hashing to a peer returning 4xx/5xx; single-flight collapses N concurrent requests onto one failing peer HTTP call, so many callers get this error at once.

Common situations: Peer registered with wrong port/path (404); peer overloaded returning 500; peer down behind a proxy returning 502/503; all requests for one hot key fail together because of single-flight fan-in.

Related errors


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