{"record":{"id":"c0d77609b2174c2d","repo":"thanos-io/thanos","slug":"invalid-temporality-for-metric-q","errorCode":null,"errorMessage":"invalid temporality for metric %q","messagePattern":"invalid temporality for metric %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/otlptranslator/metrics_to_prw.go","lineNumber":86,"sourceCode":"\t\tscopeMetricsSlice := resourceMetrics.ScopeMetrics()\n\t\t// keep track of the most recent timestamp in the ResourceMetrics for\n\t\t// use with the \"target\" info metric\n\t\tvar mostRecentTimestamp pcommon.Timestamp\n\t\tfor j := 0; j < scopeMetricsSlice.Len(); j++ {\n\t\t\tmetricSlice := scopeMetricsSlice.At(j).Metrics()\n\n\t\t\t// TODO: decide if instrumentation library information should be exported as labels\n\t\t\tfor k := 0; k < metricSlice.Len(); k++ {\n\t\t\t\tif err := c.everyN.checkContext(ctx); err != nil {\n\t\t\t\t\terrs.Add(err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tmetric := metricSlice.At(k)\n\t\t\t\tmostRecentTimestamp = max(mostRecentTimestamp, mostRecentTimestampInMetric(metric))\n\n\t\t\t\tif !isValidAggregationTemporality(metric) {\n\t\t\t\t\terrs.Add(fmt.Errorf(\"invalid temporality for metric %q\", metric.Name()))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tpromName := BuildCompliantName(metric, settings.Namespace, settings.AddMetricSuffixes, settings.AllowUTF8)\n\t\t\t\tc.metadata = append(c.metadata, prompb.MetricMetadata{\n\t\t\t\t\tType:             otelMetricTypeToPromMetricType(metric),\n\t\t\t\t\tMetricFamilyName: promName,\n\t\t\t\t\tHelp:             metric.Description(),\n\t\t\t\t\tUnit:             metric.Unit(),\n\t\t\t\t})\n\n\t\t\t\t// handle individual metrics based on type\n\t\t\t\t//exhaustive:enforce\n\t\t\t\tswitch metric.Type() {\n\t\t\t\tcase pmetric.MetricTypeGauge:\n\t\t\t\t\tdataPoints := metric.Gauge().DataPoints()\n\t\t\t\t\tif dataPoints.Len() == 0 {\n\t\t\t\t\t\terrs.Add(fmt.Errorf(\"empty data points. %s is dropped\", metric.Name()))","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/otlptranslator/metrics_to_prw.go#L68-L104","documentation":"FromMetrics iterates all OTLP metrics and checks isValidAggregationTemporality per metric. Only cumulative (and delta for certain types) temporality is supported for Prometheus remote-write translation; a metric with an unsupported temporality (e.g. unspecified) adds this error and skips the metric.","triggerScenarios":"Sending OTLP metrics whose AggregationTemporality is TemporalityUnspecified or a temporality unsupported for that metric type (e.g. delta gauge-like sums depending on feature gates) through the OTLP->PRW converter.","commonSituations":"Producers/SConstructors that forget to set temporality on histogram/sum instruments; gateways stripping temporality; mixing cumulative and delta streams; OTLP exporters configured for delta when the receiver only accepts cumulative.","solutions":["Configure the exporter/SDK to emit cumulative temporality (default) or the temporality the receiver accepts","Fix producers that construct metrics without setting AggregationTemporality explicitly","Use the collector deltatocumulative or aggregate processors to convert delta to cumulative before forwarding","Check which metric names are listed in the error set and align their instrument temporality settings"],"exampleFix":"# before: exporter configured for unsupported temporality\notlp: \n  temporality_preference: delta\n# after\notlp:\n  temporality_preference: cumulative","handlingStrategy":"validation","validationCode":"for _, m := range ms {\n    if !isValidAggregationTemporality(m) {\n        log.Warnf(\"metric %q has unsupported temporality %v\", m.Name(), m.AggregationTemporality())\n    }\n}","typeGuard":"func supportedTemporality(m pmetric.Metric) bool {\n    switch m.Type() {\n    case pmetric.MetricTypeHistogram:\n        return m.Histogram().AggregationTemporality() == pmetric.AggregationTemporalityCumulative\n    case pmetric.MetricTypeExponentialHistogram:\n        return m.ExponentialHistogram().AggregationTemporality() == pmetric.AggregationTemporalityCumulative\n    case pmetric.MetricTypeSum:\n        return m.Sum().AggregationTemporality() == pmetric.AggregationTemporalityCumulative\n    default:\n        return true\n    }\n}","tryCatchPattern":"_, err := translator.FromMetrics(ctx, md, settings)\nif err != nil {\n    var annots annotations.Annotations\n    if errors.As(err, &annots) {\n        for _, a := range annots {\n            if strings.Contains(a.Error(), \"invalid temporality\") {\n                log.Warnf(\"skipped metric: %v\", a)\n                continue\n            }\n        }\n    }\n}","preventionTips":["Set temporality_preference: cumulative on all OTLP exporters","Reject or convert delta metrics at the collector boundary","Validate metric payloads in a staging pipeline before production"],"tags":["otlp","temporality","metrics"],"backgroundTag":"invalid-enum-value","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"}