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

  1. Inspect the wrapped underlying error (err.Error()) to distinguish network reset from decode failure.
  2. Ensure client reply type matches what the server method writes into its second argument.
  3. 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

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.