influxdata/influxdb · error
cannot fit duration into u64
Error message
cannot fit duration into u64
What it means
DurationCounter stores durations as nanosecond counts in a U64Counter. inc() converts the Duration via as_nanos() (u128) and try_into::<u64>(); durations longer than u64::MAX nanoseconds (about 584 years) cannot fit and the expect panics. Real elapsed times never approach this - it fires only on absurd or broken Duration values.
Source
Thrown at core/metric/src/duration.rs:25
use std::convert::TryInto;
/// The maximum duration that can be stored in the duration measurements
pub const DURATION_MAX: Duration = Duration::from_nanos(u64::MAX);
/// A monotonic counter of `std::time::Duration`
#[derive(Debug, Clone, Default)]
pub struct DurationCounter {
inner: U64Counter,
}
impl DurationCounter {
pub fn inc(&self, duration: Duration) {
self.inner.inc(
duration
.as_nanos()
.try_into()
.expect("cannot fit duration into u64"),
)
}
pub fn fetch(&self) -> Duration {
Duration::from_nanos(self.inner.fetch())
}
}
impl MetricObserver for DurationCounter {
type Recorder = Self;
fn kind() -> MetricKind {
MetricKind::DurationCounter
}
fn recorder(&self) -> Self::Recorder {
self.clone()
}View on GitHub (pinned to d28e26e048)
Solutions
- Find the code producing the Duration - anything over ~584 years means an arithmetic or unit bug upstream
- Report per-interval durations instead of accumulating them into a single Duration
- Clamp before recording: d = std::cmp::min(d, Duration::from_secs(3600))
- At the call site, convert defensively: d.as_nanos().try_into().unwrap_or(u64::MAX) instead of relying on the library's expect
Example fix
// before counter.inc(total_elapsed); // accumulated across the whole process -> can be huge // after counter.inc(interval_elapsed.min(Duration::from_secs(3600)));
Defensive patterns
Strategy: validation
Validate before calling
// bound any duration before it reaches the metric
fn clamp_duration(d: Duration) -> Duration {
d.min(Duration::from_secs(3600))
}
counter.inc(clamp_duration(measured));
Type guard
fn fits_u64_nanos(d: Duration) -> bool {
u64::try_from(d.as_nanos()).is_ok()
}
Prevention
- Record per-interval durations; never accumulate them into one Duration
- Fix unit/sign bugs where negative i64 nanosecond deltas become huge unsigned values
- Debug-assert durations against a sane upper bound (e.g. 1 hour) during development
When it happens
Trigger: Calling counter.inc(duration) with Duration::MAX, or with a Duration produced by arithmetic bugs such as Duration::from_secs(u64::MAX), saturating accumulation across retry loops, or a duration built from a wrapped/negative i64 nanoseconds cast.
Common situations: Retry/storm loops that accumulate elapsed time into one Duration before reporting it once; conversions where a negative i64 nanosecond delta became a huge unsigned value.
Related errors
- metric should be in progress
- no metric in progress
- timestamp, {}, out of range for precision: {:?}
- schema contains non-existent or column
- schema contains repeated column name
AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16).
Data as JSON: /api/errors/709e448967857cdb.
Report an issue: GitHub.