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

  1. Find the code producing the Duration - anything over ~584 years means an arithmetic or unit bug upstream
  2. Report per-interval durations instead of accumulating them into a single Duration
  3. Clamp before recording: d = std::cmp::min(d, Duration::from_secs(3600))
  4. 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

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


AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16). Data as JSON: /api/errors/709e448967857cdb. Report an issue: GitHub.