VictoriaMetrics/VictoriaMetrics · error
cannot unmarshal Positive: %w
Error message
cannot unmarshal Positive: %w
What it means
Wrap of the error returned by buckets.decodeBuckets when unmarshaling the `positive` Buckets submessage (field 8) of an ExponentialHistogramDataPoint. The embedded message bytes were obtained, but their internal fields (offset / bucket_counts) could not be parsed. The wrapped error names the exact inner field that failed.
Source
Thrown at lib/protoparser/opentelemetry/pb/pb.go:1377
}
ehctx.hasSum = true
case 6:
ehctx.scale, ok = fc.Sint32()
if !ok {
return fmt.Errorf("cannot read Scale")
}
case 7:
ehctx.zeroCount, ok = fc.Fixed64()
if !ok {
return fmt.Errorf("cannot read ZeroCount")
}
case 8:
data, ok := fc.MessageData()
if !ok {
return fmt.Errorf("cannot read Positive buckets")
}
if err := ehctx.positive.decodeBuckets(data); err != nil {
return fmt.Errorf("cannot unmarshal Positive: %w", err)
}
case 9:
data, ok := fc.MessageData()
if !ok {
return fmt.Errorf("cannot read Negative buckets")
}
if err := ehctx.negative.decodeBuckets(data); err != nil {
return fmt.Errorf("cannot unmarshal Negative: %w", err)
}
case 10:
ehctx.flags, ok = fc.Uint32()
if !ok {
return fmt.Errorf("cannot read Flags")
}
case 12:
ehctx.min, ok = fc.Double()
if !ok {
return fmt.Errorf("cannot read Min")View on GitHub (pinned to 5079fb58f1)
Solutions
- Inspect the wrapped inner error to see which bucket field failed, then fix the producer serialization for that field.
- Re-send the batch; if reproducible, decode the payload with google.golang.org/protobuf to confirm the message is invalid per the proto spec.
- Align opentelemetry-proto versions between the SDK/collector emitting metrics and the ingestion endpoint.
- If you are writing the exporter yourself, use the generated proto marshalers instead of hand-packing bucket fields.
Example fix
// before: hand-packed buckets with varint wire type for field 1
mm.AppendInt32(1, buckets.Offset)
// after: offset is sint32 in proto; use the generated marshaler
bucketMsg := &metricspb.ExponentialHistogramDataPoint_Buckets{Offset: buckets.Offset, BucketCounts: buckets.Counts}
mm.AppendMessage(8) // then marshal bucketMsg into it Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate with the generated types, which check nested Buckets fields too
var req metricspb.ExportMetricsServiceRequest
if err := proto.Unmarshal(payload, &req); err != nil {
return fmt.Errorf("invalid OTLP payload: %w", err)
} Try / catch
if err := decode(data); err != nil {
var inner error
if errors.Unwrap(err) != nil {
inner = errors.Unwrap(err) // reveals which bucket field failed
}
log.Error("failed to decode positive buckets", "wrapped", inner)
metrics.MalformedPayloads.Inc()
return nil // skip instead of failing the whole request
} Prevention
- Use generated proto marshalers (AppendSint32/AppendUint64) rather than manual field packing
- Version-lock opentelemetry-proto across the pipeline
- Monitor for this error rate as an indicator of a broken upstream exporter
- Checksum payloads when storing/replaying them through queues
When it happens
Trigger: Parsing OTLP metrics where the positive Buckets submessage contains field 1 (offset) or field 2 (bucket_counts) with an unexpected wire type, or the submessage bytes are internally truncated so NextField fails.
Common situations: Version drift between producers and consumers of opentelemetry-proto (a field repurposed with a different type), corrupted telemetry queues, or fuzz/hand-written exporters emitting malformed bucket data.
Related errors
- cannot read Negative buckets
- cannot unmarshal Negative: %w
- cannot read Histogram data
- cannot unmarshal Histogram: %w
- cannot read Positive buckets
AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03).
Data as JSON: /api/errors/b45061242c152dd5.
Report an issue: GitHub.