geektutu/7days-golang · error
reading body
Error message
reading body
What it means
In receive(), the response header parsed OK but reading the reply body into call.Reply failed, so the call is failed with "reading body " + err.Error(). Typically the connection broke mid-response or the body doesn't fit/match the expected type.
Source
Thrown at gee-rpc/day2-client/client.go:152
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
- Retry the call on a fresh connection (the client terminates pending calls on this error)
- Register reply types with gob.Register on both sides if decode errors appear after "reading body " Ensure Reply is a non-nil pointer to the correct struct
- Check server logs for panics/truncation during response write
Example fix
// before
call := client.Go("Foo.Sum", args, nil, nil).Done // nil reply -> body read fails
// after
reply := new(FooSumReply)
call := client.Go("Foo.Sum", args, reply, nil).Done Defensive patterns
Strategy: retry
Validate before calling
if reflect.ValueOf(reply).Kind() != reflect.Ptr || reflect.ValueOf(reply).IsNil() {
return errors.New("reply must be a non-nil pointer")
} Try / catch
if err := client.Call(method, args, reply); err != nil {
if strings.HasPrefix(err.Error(), "reading body ") {
// decode/transport issue: re-dial and retry once; check gob registration
return retryOnFreshConn(method, args, reply)
}
return err
} Prevention
- gob.Register all reply types on client and server
- Always pass non-nil pointers for Reply
- Configure keepalives to survive LB idle timeouts
- Check server logs for mid-response panics/truncation
When it happens
Trigger: Server closes the connection after writing the header; network reset/EOF mid-body; codec cannot decode the body into call.Reply (type mismatch, wrong gob type registration); server crashed mid-response.
Common situations: Server panics while writing a large response; reply struct not gob.Register()ed causing decode errors; idle connections killed by a load balancer; passing a nil or wrong-typed Reply pointer.
Related errors
AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03).
Data as JSON: /api/errors/43c42eb7aa83b591.
Report an issue: GitHub.