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

  1. Check the client's received m.Error / error header for the wrapped cause
  2. Fix the response type so it is encodable by the negotiated codec (no chan/func/cycles)
  3. Register protobuf types correctly (proto.RegisterType) when using the proto codec
  4. Ensure client and server use compatible codecs (json vs proto vs bytes)
  5. 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

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


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/016008bc717428ac. Report an issue: GitHub.