{"record":{"id":"b842cb1f75873026","repo":"VictoriaMetrics/VictoriaMetrics","slug":"cannot-read-flags","errorCode":null,"errorMessage":"cannot read Flags","messagePattern":"cannot read Flags","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/protoparser/opentelemetry/pb/pb.go","lineNumber":891,"sourceCode":"\t\t\ttimestamp, ok = fc.Fixed64()\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"cannot read TimeUnixNano\")\n\t\t\t}\n\t\tcase 4:\n\t\t\tvalue, ok = fc.Double()\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"cannot read DoubleValue\")\n\t\t\t}\n\t\tcase 6:\n\t\t\tintValue, ok := fc.Sfixed64()\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"cannot read IntValue\")\n\t\t\t}\n\t\t\tvalue = float64(intValue)\n\t\tcase 8:\n\t\t\tflags, ok = fc.Uint32()\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"cannot read Flags\")\n\t\t\t}\n\t\t}\n\t}\n\n\tdctx.mp.PushSample(&dctx.mm, \"\", &dctx.ls, timestamp, value, flags)\n\n\treturn nil\n}\n\n// Sum represents the corresponding OTEL protobuf message\n//\n// See https://github.com/open-telemetry/opentelemetry-proto/blob/049d4332834935792fd4dbd392ecd31904f99ba2/opentelemetry/proto/metrics/v1/metrics.proto#L240\ntype Sum struct {\n\tDataPoints  []*NumberDataPoint\n\tIsMonotonic bool\n}\n\nfunc (s *Sum) marshalProtobuf(mm *easyproto.MessageMarshaler) {","sourceCodeStart":873,"sourceCodeEnd":909,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/protoparser/opentelemetry/pb/pb.go#L873-L909","documentation":"Field 8 of NumberDataPoint is flags, a uint32. fc.Uint32() returns ok=false when field 8 arrives with a wire type other than varint (type 0) — e.g. it was encoded as fixed32/fixed64 or length-delimited — so the decoder returns 'cannot read Flags'. Flags carry data-point flags such as the no-recorded-value mask, so a wrong encoding also silently corrupts flag semantics if forced.","triggerScenarios":"Producer encodes flags as fixed32/fixed64 or bytes instead of varint; flags field declared as a different type in a modified .proto; corrupted or fuzzed bytes on field 8.","commonSituations":"Hand-rolled serializers using AppendFixed32 for flags; generated code from a tweaked .proto (fixed32 flags); intermediary components rewriting datapoints; fuzz tests.","solutions":["Encode flags as a varint uint32 (AppendUint32, wire type 0) exactly as metrics.proto declares.","Regenerate serialization code from the canonical opentelemetry-proto file.","Verify field 8's wire type with protoc --decode on the producer's output.","Use the official OTel SDK marshaller so flags encoding matches the schema."],"exampleFix":"// before: flags as fixed32\nmm.AppendFixed32(8, flags)\n\n// after: flags as varint uint32\nmm.AppendUint32(8, flags)","handlingStrategy":"validation","validationCode":"// Producer-side: flags must be varint uint32 on field 8\nvar mm easyproto.MessageMarshaler\nmm.AppendUint32(8, flags) // wire type 0\n// wrong: mm.AppendFixed32(8, flags) -> \"cannot read Flags\"","typeGuard":"func field8IsVarint(dataPointBytes []byte) bool {\n    return scanWireType(dataPointBytes, 8) == 0\n}","tryCatchPattern":"if err := importer.ImportOtlpMetrics(ctx, payload); err != nil {\n    if strings.Contains(err.Error(), \"cannot read Flags\") {\n        log.Error(\"flags field 8 not encoded as varint uint32\", \"err\", err)\n        return errBadProducer\n    }\n    return err\n}","preventionTips":["Use AppendUint32 (varint) for flags — fixed32/fixed64 encodings are rejected.","Only set flags values defined by the OTel spec (e.g. no-recorded-value mask 0x1).","Keep generated serialization code in sync with canonical metrics.proto.","Add exporter tests that decode field 8 and assert wire type 0."],"tags":["protobuf","opentelemetry","wire-type","flags"],"backgroundTag":"protobuf-wire-type-mismatch","analyzedSha":"5079fb58f1e8e62113f90c945ad71586c797d770","analyzedAt":"2026-09-03T18:10:26.153Z","contentChangedAt":"2026-09-03T18:10:26.153Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}