micro/go-micro · error
Unable to encode body
Error message
Unable to encode body
What it means
In the RPC codec's Write path, when the codec fails to encode the response body, the socket buffer is reset and the error is recorded into the message's Error field and error header (as 'Unable to encode body: ...') so the client receives an in-band error instead of a malformed frame. The wrap happens because the server must report encode failures over the wire.
Source
Thrown at server/rpc_codec.go:325
}
setHeaders(m, r)
// the body being sent
var body []byte
// is it a raw frame?
if v, ok := b.(*raw.Frame); ok {
body = v.Data
// if we have encoded data just send it
} else if len(r.Body) > 0 {
body = r.Body
// write the body to codec
} else if err := c.codec.Write(m, b); err != nil {
c.buf.wbuf.Reset()
// write an error if it failed
m.Error = errors.Wrapf(err, "Unable to encode body").Error()
m.Header[headers.Error] = m.Error
// no body to write
if err := c.codec.Write(m, nil); err != nil {
return err
}
} else {
// set the body
body = c.buf.wbuf.Bytes()
}
// Set content type if theres content
if len(body) > 0 {
m.Header["Content-Type"] = c.req.Header["Content-Type"]
}
// send on the socket
return c.socket.Send(&transport.Message{
Header: m.Header,View on GitHub (pinned to 24529f1404)
Solutions
- Check the client's received m.Error / error header for the wrapped cause
- Fix the response type so it is encodable by the negotiated codec (no chan/func/cycles)
- Register protobuf types correctly (proto.RegisterType) when using the proto codec
- Ensure client and server use compatible codecs (json vs proto vs bytes)
- Return a simple serializable DTO from the handler instead of raw internal types
Example fix
// before
func (h *Handler) Get(ctx, req) (*Response, error) {
return &Response{Callback: cb}, nil // chan/func field breaks codec
}
// after
type Response struct{ Data string `json:"data"` } // plain serializable fields
return &Response{Data: result}, nil Defensive patterns
Strategy: try-catch
Validate before calling
// validate the handler response is encodable before returning it
if err := json.Marshal(resp); err != nil {
return nil, status.Errorf(codes.Internal, "response not encodable: %v", err)
} Try / catch
// client side
if err := client.Call(ctx, req, rsp); err != nil {
if strings.Contains(err.Error(), "Unable to encode body") {
log.Printf("server failed to encode response: %v — check response types/codec", err)
}
return err
} Prevention
- Keep RPC response types plain and serializable (no chan/func/cycles)
- Register protobuf types when using the proto codec
- Keep client and server codecs compatible
- Write handler tests that round-trip the response through the chosen codec
When it happens
Trigger: A server RPC handler returns a response that the codec cannot encode: unsupported types in the response struct (funcs, channels, cycles for JSON codec), protobuf messages not registered, or nil response where a typed body is required.
Common situations: Returning Go structs containing func/chan fields from a JSON-codec handler; protobuf response types not registered via proto.Register; cyclic data in response payloads; mismatched codec between client and server.
Related errors
- ErrInvalidMessage
- failed to marshal: %v is not type of *bytes.Frame or proto.M
- failed to unmarshal: %v is not type of proto.Message
- failed to marshal: %v is not type of *[]byte
- failed to unmarshal: %v is not type of *[]byte
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/016008bc717428ac.
Report an issue: GitHub.