{"record":{"id":"f51f5fd0ca4ac610","repo":"thanos-io/thanos","slug":"error-marshaling-proto-response-v","errorCode":null,"errorMessage":"error marshaling proto response: %v","messagePattern":"error marshaling proto response: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/cortex/util/http.go","lineNumber":257,"sourceCode":"\treturn nil, nil\n}\n\n// tryBufferFromReader attempts to cast the reader to a `*bytes.Buffer` this is possible when using httpgrpc.\n// If it fails it will return nil and false.\nfunc tryBufferFromReader(reader io.Reader) (*bytes.Buffer, bool) {\n\tif bufReader, ok := reader.(interface {\n\t\tBytesBuffer() *bytes.Buffer\n\t}); ok && bufReader != nil {\n\t\treturn bufReader.BytesBuffer(), true\n\t}\n\treturn nil, false\n}\n\n// SerializeProtoResponse serializes a protobuf response into an HTTP response.\nfunc SerializeProtoResponse(w http.ResponseWriter, resp proto.Message, compression CompressionType) error {\n\tdata, err := proto.Marshal(resp)\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn fmt.Errorf(\"error marshaling proto response: %v\", err)\n\t}\n\n\tswitch compression {\n\tcase NoCompression:\n\tcase RawSnappy:\n\t\tdata = snappy.Encode(nil, data)\n\t}\n\n\tif _, err := w.Write(data); err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn fmt.Errorf(\"error sending proto response: %v\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":239,"sourceCodeEnd":273,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/internal/cortex/util/http.go#L239-L273","documentation":"SerializeProtoResponse marshals a protobuf response message to bytes before writing it to the HTTP response; if proto.Marshal fails, it writes a 500 to the client and returns this wrapped error. Marshal failures indicate the response message is invalid (e.g. required fields unset in older proto2 semantics, unknown enum values, or a nil/non-initializable message).","triggerScenarios":"Calling SerializeProtoResponse with a resp message that proto.Marshal cannot serialize — typically a nil message, a message with invalid oneof/enum state, or corruption of the message structure.","commonSituations":"Handlers populating response protos incorrectly (wrong oneof branch, invalid enum number from manual field assignment), or passing nil after an upstream error path.","solutions":["Ensure resp is non-nil and properly initialized before calling SerializeProtoResponse","Check that all assigned enum values and oneof fields are valid for the proto definition","Regenerate Go proto code if .pb.go files are out of sync with the .proto definitions","Log the underlying error to identify which field/branch of the message is invalid"],"exampleFix":"// before\nreturn util.SerializeProtoResponse(w, nil, compression)\n// after\nif resp == nil {\n    return errors.New(\"nil proto response\")\n}\nreturn util.SerializeProtoResponse(w, resp, compression)","handlingStrategy":"try-catch","validationCode":"if resp == nil {\n    return errors.New(\"proto response is nil\")\n}\nif _, err := proto.Marshal(resp); err != nil {\n    return fmt.Errorf(\"response not marshallable: %w\", err)\n}","typeGuard":"func isMarshallable(m proto.Message) bool {\n    if m == nil { return false }\n    _, err := proto.Marshal(m)\n    return err == nil\n}","tryCatchPattern":"if err := util.SerializeProtoResponse(w, resp, compression); err != nil {\n    if strings.Contains(err.Error(), \"error marshaling proto response\") {\n        log.Errorf(\"bad response proto: %v\", err)\n        http.Error(w, \"internal serialization failure\", http.StatusInternalServerError)\n        return\n    }\n    return err\n}","preventionTips":["Always check for nil responses before serialization","Regenerate proto code after schema changes","Assign enum/oneof values only through generated setters"],"tags":["protobuf","http","serialization"],"backgroundTag":"json-marshal-failed","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}