thanos-io/thanos · warning

empty data points. is dropped

Error message

empty data points. %s is dropped

What it means

For gauge metrics, FromMetrics checks that the data point slice is non-empty before conversion. An OTLP gauge with zero data points contributes nothing to remote write, so this error is recorded as an annotation and the metric is dropped (not a hard failure of the whole batch).

Solutions

  1. Fix the exporter/collector to not emit gauges with empty data point lists
  2. Configure processors (filter, transform) to drop empty metrics entirely rather than stripping points
  3. Ensure the SDK actually records the gauge before export
  4. Treat as informational: the metric is dropped and conversion continues
Defensive patterns

Strategy: validation

Validate before calling

for _, m := range ms {
    if m.Type() == pmetric.MetricTypeGauge && m.Gauge().DataPoints().Len() == 0 {
        log.Warnf("gauge %q has no data points; it will be dropped", m.Name())
    }
}

Type guard

func gaugeHasPoints(m pmetric.Metric) bool {
    return m.Type() != pmetric.MetricTypeGauge || m.Gauge().DataPoints().Len() > 0
}

Try / catch

_, err := translator.FromMetrics(ctx, md, settings)
if err != nil {
    var annots annotations.Annotations
    if errors.As(err, &annots) {
        for _, a := range annots {
            if strings.Contains(a.Error(), "empty data points") {
                log.Warnf("dropped empty metric: %v", a)
            }
        }
    }
}

Prevention

When it happens

Trigger: An OTLP MetricSummary of type Gauge whose Gauge().DataPoints() length is 0 — exporters sending metric envelopes with no data points (e.g. no-samples windows), from AddMetrics on a payload containing empty gauges.

Common situations: Exporters that emit metric descriptors every scrape even with zero samples; filter/transform processors in the collector removing all points but leaving the metric; SDKs emitting gauge shells when no measurement was recorded.

Understand the failure class

Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/8543d603765c207f. Report an issue: GitHub.

Appendix: source

Thrown at pkg/receive/otlptranslator/metrics_to_prw.go:104

					errs.Add(fmt.Errorf("invalid temporality for metric %q", metric.Name()))
					continue
				}

				promName := BuildCompliantName(metric, settings.Namespace, settings.AddMetricSuffixes, settings.AllowUTF8)
				c.metadata = append(c.metadata, prompb.MetricMetadata{
					Type:             otelMetricTypeToPromMetricType(metric),
					MetricFamilyName: promName,
					Help:             metric.Description(),
					Unit:             metric.Unit(),
				})

				// handle individual metrics based on type
				//exhaustive:enforce
				switch metric.Type() {
				case pmetric.MetricTypeGauge:
					dataPoints := metric.Gauge().DataPoints()
					if dataPoints.Len() == 0 {
						errs.Add(fmt.Errorf("empty data points. %s is dropped", metric.Name()))
						break
					}
					if err := c.addGaugeNumberDataPoints(ctx, dataPoints, resource, settings, promName); err != nil {
						errs.Add(err)
						if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
							return
						}
					}
				case pmetric.MetricTypeSum:
					dataPoints := metric.Sum().DataPoints()
					if dataPoints.Len() == 0 {
						errs.Add(fmt.Errorf("empty data points. %s is dropped", metric.Name()))
						break
					}
					if err := c.addSumNumberDataPoints(ctx, dataPoints, resource, metric, settings, promName); err != nil {
						errs.Add(err)
						if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
							return

View on GitHub (pinned to 35b8b99117)