geektutu/7days-golang · error
reading response body: %v
Error message
reading response body: %v
What it means
In the day7 build, after a 200 response from a peer, the body bytes are read and then handed to the caller; an ioutil.ReadAll failure is wrapped as "reading response body: %v". The proto decoding has its own separate error, so this one strictly indicates an I/O problem while streaming the body.
Source
Thrown at gee-cache/day7-proto-buf/geecache/http.go:132
u := fmt.Sprintf(
"%v%v/%v",
h.baseURL,
url.QueryEscape(in.GetGroup()),
url.QueryEscape(in.GetKey()),
)
res, err := http.Get(u)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return fmt.Errorf("server returned: %v", res.Status)
}
bytes, err := ioutil.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("reading response body: %v", err)
}
if err = proto.Unmarshal(bytes, out); err != nil {
return fmt.Errorf("decoding response body: %v", err)
}
return nil
}
var _ PeerGetter = (*httpGetter)(nil)
View on GitHub (pinned to cf36443821)
Solutions
- Retry the peer fetch (single-flight will coalesce concurrent retries)
- Configure a sane http.Client.Timeout on the peer client
- Inspect the wrapped error (timeout vs reset) and adjust the responsible layer (LB, proxy, keep-alives)
- Check peer health/memory if responses are being cut off consistently
Example fix
// before
client := &http.Client{}
bytes, err := ioutil.ReadAll(res.Body)
// after
client := &http.Client{Timeout: 5 * time.Second}
bytes, err := io.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("reading response body (peer %s): %w", peerAddr, err)
} Defensive patterns
Strategy: retry
Validate before calling
client := &http.Client{Timeout: 5 * time.Second}
if res.ContentLength == 0 {
return errors.New("empty peer response")
} Try / catch
err := g.Get(ctx, key, &out)
if err != nil && strings.Contains(err.Error(), "reading response body") {
// transient I/O failure mid-body: retry once
return g.Get(ctx, key, &out)
} Prevention
- Set explicit client timeouts; avoid default transport quirks
- Confirm intermediaries don't cut long protobuf responses
- Track node restarts/OOMs — they manifest as body-read failures
- Include the peer address in your own error wrapping for faster triage
When it happens
Trigger: Peer connection reset or closed after headers during a protobuf response transfer; client timeout expiring mid-read; intermediary dropping the response.
Common situations: Unstable inter-node networks; pod restarts mid-response; undersized client timeouts under load; large values slow to serialize/transfer.
Related errors
- reading response body: %v
- reading response body: %v
- server returned: %v
- server returned: %v
- server returned: %v
AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03).
Data as JSON: /api/errors/c130bc5de1afb1b8.
Report an issue: GitHub.