{"record":{"id":"016008bc717428ac","repo":"micro/go-micro","slug":"unable-to-encode-body","errorCode":null,"errorMessage":"Unable to encode body","messagePattern":"Unable to encode body","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/rpc_codec.go","lineNumber":325,"sourceCode":"\t}\n\n\tsetHeaders(m, r)\n\n\t// the body being sent\n\tvar body []byte\n\n\t// is it a raw frame?\n\tif v, ok := b.(*raw.Frame); ok {\n\t\tbody = v.Data\n\t\t// if we have encoded data just send it\n\t} else if len(r.Body) > 0 {\n\t\tbody = r.Body\n\t\t// write the body to codec\n\t} else if err := c.codec.Write(m, b); err != nil {\n\t\tc.buf.wbuf.Reset()\n\n\t\t// write an error if it failed\n\t\tm.Error = errors.Wrapf(err, \"Unable to encode body\").Error()\n\t\tm.Header[headers.Error] = m.Error\n\t\t// no body to write\n\t\tif err := c.codec.Write(m, nil); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// set the body\n\t\tbody = c.buf.wbuf.Bytes()\n\t}\n\n\t// Set content type if theres content\n\tif len(body) > 0 {\n\t\tm.Header[\"Content-Type\"] = c.req.Header[\"Content-Type\"]\n\t}\n\n\t// send on the socket\n\treturn c.socket.Send(&transport.Message{\n\t\tHeader: m.Header,","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/server/rpc_codec.go#L307-L343","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nfunc (h *Handler) Get(ctx, req) (*Response, error) {\n    return &Response{Callback: cb}, nil // chan/func field breaks codec\n}\n// after\ntype Response struct{ Data string `json:\"data\"` } // plain serializable fields\nreturn &Response{Data: result}, nil","handlingStrategy":"try-catch","validationCode":"// validate the handler response is encodable before returning it\nif err := json.Marshal(resp); err != nil {\n    return nil, status.Errorf(codes.Internal, \"response not encodable: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"// client side\nif err := client.Call(ctx, req, rsp); err != nil {\n    if strings.Contains(err.Error(), \"Unable to encode body\") {\n        log.Printf(\"server failed to encode response: %v — check response types/codec\", err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["rpc","codec","serialization","server"],"backgroundTag":"rpc-body-encode-failed","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}