geektutu/7days-golang · error
reading body
Error message
reading body
What it means
In the client's receive loop, reading the reply body into call.Reply failed. The underlying codec/IO error is wrapped as "reading body " + err, stored in call.Error, and the pending call is then terminated. This typically indicates corrupted or truncated reply data on the connection.
Source
Thrown at gee-rpc/day7-registry/client.go:157
for err == nil {
var h codec.Header
if err = client.cc.ReadHeader(&h); err != nil {
break
}
call := client.removeCall(h.Seq)
switch {
case call == nil:
// it usually means that Write partially failed
// and call was already removed.
err = client.cc.ReadBody(nil)
case h.Error != "":
call.Error = fmt.Errorf(h.Error)
err = client.cc.ReadBody(nil)
call.done()
default:
err = client.cc.ReadBody(call.Reply)
if err != nil {
call.Error = errors.New("reading body " + err.Error())
}
call.done()
}
}
// error occurs, so terminateCalls pending calls
client.terminateCalls(err)
}
// Go invokes the function asynchronously.
// It returns the Call structure representing the invocation.
func (client *Client) Go(serviceMethod string, args, reply interface{}, done chan *Call) *Call {
if done == nil {
done = make(chan *Call, 10)
} else if cap(done) == 0 {
log.Panic("rpc client: done channel is unbuffered")
}
call := &Call{
ServiceMethod: serviceMethod,View on GitHub (pinned to cf36443821)
Solutions
- Inspect the wrapped underlying error (err.Error()) to distinguish network reset from decode failure.
- Ensure client reply type matches what the server method writes into its second argument.
- Verify both sides use the same codec/option (MagicNumber, CodecType); recreate the connection after this error since terminateCalls shuts the client down.
Example fix
// before
type Reply struct{ A string }
// server returns {"sum": 10} — decode fails
// after
type Reply struct{ Sum int } // align reply struct with server's response Defensive patterns
Strategy: retry
Validate before calling
// ensure reply struct mirrors the server's response type
var _ = func() error {
var reply server.Reply
_ = &reply // keep types in a shared package to prevent drift
return nil
} Try / catch
if err := client.Call(ctx, "Foo.Sum", args, reply); err != nil && strings.HasPrefix(err.Error(), "reading body") {
client, _ = geeRPC.XDial(addr) // connection was terminated, rebuild and retry
} Prevention
- Share request/reply types between client and server in a common package.
- Match CodecType/MagicNumber options on both ends.
- Set keepalives/timeouts so reset connections are detected early.
When it happens
Trigger: Server wrote a header but the body was malformed, connection reset mid-body, reply type not decodable into call.Reply (type mismatch between client reply and server response), or server crashed while writing the response.
Common situations: Version/codec mismatch between client and server options, mismatched reply struct types between client and server, network interruption or proxy timeout cutting the response, or server panics mid-serialization.
Related errors
AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03).
Data as JSON: /api/errors/72687dff4506ff85.
Report an issue: GitHub.