{"record":{"id":"7b4d01bedf0ffe49","repo":"thanos-io/thanos","slug":"proto-statistic-wiretype-end-group-for-non-group","errorCode":null,"errorMessage":"proto: Statistic: wiretype end group for non-group","messagePattern":"proto: Statistic: wiretype end group for non-group","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/status/statuspb/rpc.pb.go","lineNumber":1846,"sourceCode":"\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowRpc\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= uint64(b&0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: Statistic: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: Statistic: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Name\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowRpc\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]","sourceCodeStart":1828,"sourceCodeEnd":1864,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/status/statuspb/rpc.pb.go#L1828-L1864","documentation":"In the generated Unmarshal loop for the Statistic message (pkg/status/statuspb/rpc.pb.go:1846), a wire type of 4 means 'end group', which is only valid inside a group field. Since Statistic is not a group, this error indicates the byte stream is structurally invalid or produced from a different schema.","triggerScenarios":"Unmarshaling bytes where the tag for the next field of Statistic has wire type 4 — caused by desynchronized parsing (an earlier field consumed the wrong number of bytes), group-encoded data, or a corrupted payload.","commonSituations":"Corrupted/truncated gRPC response bodies; a sender built from an incompatible .proto that shifts field boundaries so the receiver reads a tag mid-field; reusing a marshaled buffer incorrectly.","solutions":["Fix the upstream schema mismatch by aligning both peers on the same generated statuspb code","Re-sync parsing: if an earlier field error occurred, the stream is desynchronized — start unmarshal from the message start, not mid-buffer","Validate the transport (compression, proxy) is not corrupting frames","Re-marshal and hex-dump the message on the sender side to compare against the receiver's expectations"],"exampleFix":"// before: parsing mid-buffer\nmsg.Unmarshal(buf[offset:])\n// after\nmsg.Unmarshal(buf) // start from the full serialized message","handlingStrategy":"try-catch","validationCode":"if len(buf) == 0 || buf[0] == 0 {\n    return errors.New(\"empty or malformed protobuf frame\")\n}","typeGuard":null,"tryCatchPattern":"if err := proto.Unmarshal(buf, &stat); err != nil {\n    if strings.Contains(err.Error(), \"end group for non-group\") {\n        return fmt.Errorf(\"corrupt or desynchronized protobuf frame: %w\", err)\n    }\n    return err\n}","preventionTips":["Never unmarshal from a mid-buffer offset; always start at a message boundary","Discard the whole frame after any unmarshal error instead of retrying the remainder","Check proxies/compressors for gRPC frame corruption","Fuzz-test unmarshal paths with random bytes to confirm graceful failure"],"tags":["protobuf","grpc","deserialization","wire-format","corruption"],"backgroundTag":"protobuf-unmarshal-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"}