influxdata/influxdb · error
no metric in progress
Error message
no metric in progress
What it means
PrometheusTextEncoder (core/metric_exporters) implements metric::Reporter for the Prometheus text exposition format. start_metric opens a metric family (stored as Option<(MetricFamily, bool)>), report_observation appends labeled samples, and finishing closes it. report_observation panics with 'no metric in progress' when no start_metric is active - called before start_metric or after the family was finished. (Symmetrically, start_metric asserts 'metric already in progress' if the previous family was never finished.)
Source
Thrown at core/metric_exporters/src/lib.rs:75
MetricKind::DurationCounter => {
(format!("{metric_name}_seconds_total"), MetricType::COUNTER)
}
MetricKind::DurationGauge => (format!("{metric_name}_seconds"), MetricType::GAUGE),
MetricKind::DurationHistogram => {
(format!("{metric_name}_seconds"), MetricType::HISTOGRAM)
}
};
let mut metric = MetricFamily::default();
metric.set_name(name);
metric.set_help(description.to_string());
metric.set_field_type(metric_type);
self.metric = Some((metric, false))
}
fn report_observation(&mut self, attributes: &Attributes, observation: Observation) {
let (metrics, used) = self.metric.as_mut().expect("no metric in progress");
let metrics = metrics.mut_metric();
let mut metric = Metric::default();
metric.set_label(
attributes
.iter()
.map(|(name, value)| {
let mut pair = LabelPair::default();
pair.set_name(name.to_string());
pair.set_value(value.to_string());
pair
})
.collect(),
);
match observation {View on GitHub (pinned to d28e26e048)
Solutions
- Emit the full ordered sequence per metric: start_metric, one or more report_observation, then finish
- When buffering/replaying observations, buffer the (name, description, kind) triple too and replay start_metric first
- Wrap the encoder in a struct that tracks 'metric open' state and asserts or logs before misordering
- Reuse the stock export paths in the metric crate rather than driving the trait by hand
Example fix
// before
encoder.report_observation(&attrs, obs); // no start_metric -> panic
// after
encoder.start_metric("requests", "count", MetricKind::U64Counter);
encoder.report_observation(&attrs, obs);
// finish_metric() when done
Defensive patterns
Strategy: validation
Validate before calling
// when replaying buffered observations, replay start_metric first
for (meta, obs) in buffered {
encoder.start_metric(meta.name, meta.description, meta.kind);
for (attrs, observation) in obs {
encoder.report_observation(&attrs, observation);
}
// finish per your Reporter impl's contract
}
Prevention
- Emit start/report/finish in strict order for every metric family
- Buffer the (name, description, kind) triple alongside observations so replay is complete
- Wrap encoders in a state-tracking struct that rejects out-of-order calls
When it happens
Trigger: Hand-driving the encoder out of order: report_observation without a preceding start_metric; reporting after the current family was finished; replaying observations captured from another reporter without replaying the start_metric call first.
Common situations: Writing custom exporters that wrap or buffer the Prometheus encoder; refactors that reorder start/report/finish; batch export logic that drops the start call for empty attribute sets.
Related errors
- metric should be in progress
- cannot fit duration into u64
- schema contains non-existent or column
- schema contains repeated column name
- can only accept once
AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16).
Data as JSON: /api/errors/3bea56280fdb7f97.
Report an issue: GitHub.