influxdata/influxdb · error
generation duration overflows u64 nanoseconds
Error message
generation duration overflows u64 nanoseconds
What it means
A `.expect(...)` panic in the v2->v3 migration when converting a v2 generation duration (a `Duration`) to `u64` nanoseconds via `u64::try_from(duration.as_nanos())`. It fires only if a v2 catalog stores a generation duration of 256+ years (`as_nanos()` exceeds `u64::MAX`), which the v3 `SetGenerationDuration` record cannot represent.
Solutions
- Locate the offending generation duration in the v2 catalog snapshot and correct it to a realistic value (e.g. seconds/hours).
- Restore the v2 catalog object from a backup taken before the bad value was written.
- If you control the source, replace `expect` with a fallible conversion and emit `MigrationError::Unexpected` instead of panicking.
- Report to InfluxData if legitimate v2 data triggers this — it indicates the migration lacks graceful overflow handling.
Example fix
// before
.expect("generation duration overflows u64 nanoseconds")
// after
.duration_ns(u64::try_from(duration.as_nanos()).map_err(|_| {
MigrationError::Unexpected(anyhow::anyhow!("generation duration {duration:?} overflows u64 ns"))
})?) Defensive patterns
Strategy: validation
Validate before calling
fn generation_duration_is_representable(d: std::time::Duration) -> bool {
u64::try_from(d.as_nanos()).is_ok()
} Type guard
fn fits_u64_nanos(v: u128) -> bool { v <= u64::MAX as u128 } Try / catch
// panic, not recoverable at runtime; pre-validate any duration you write to a v2 catalog assert!(fits_u64_nanos(d.as_nanos()), "generation duration too large for v3 migration");
Prevention
- Never write hand-tuned absurd generation durations (use seconds/minutes/hours).
- Clamp durations at write time to a sane maximum.
- Validate v2 catalog fixtures with fits_u64_nanos before migration testing.
- Prefer fallible try_from in code you own instead of expect.
When it happens
Trigger: Running `check_and_migrate_v2_to_v3` over a v2 catalog whose `generation_durations` map contains a duration whose nanosecond count does not fit in u64 (>= ~584.9 years of nanoseconds... specifically > u64::MAX ns, i.e. >= 2^64 ns).
Common situations: Hand-modified or corrupted v2 catalog snapshots with absurd generation durations; test fixtures using `Duration::MAX`; catalogs written by tooling that didn't bound-check duration values.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- row_delete_predicate_version exceeds u64
- duration not to overflow
- last cache size overflows u64
- v2 catalog should exist since checkpoint was found
- cannot fit duration into u64
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/b56f8c38fb39cabc.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_catalog/src/catalog/migrations/v3.rs:240
snapshot_next: u64,
derived_next: u64,
batch: &mut RecordBatch,
) {
if snapshot_next > derived_next {
batch.push(&SetNextId {
scope,
id: snapshot_next,
});
}
}
impl FromV2 for GenerationConfigSnapshot {
fn from_v2(&self, batch: &mut RecordBatch) {
for (level, duration) in &self.generation_durations {
batch.push(&SetGenerationDuration {
level: *level,
duration_ns: u64::try_from(duration.as_nanos())
.expect("generation duration overflows u64 nanoseconds"),
});
}
}
}
impl FromV2 for NodeSnapshot {
/// `RegisterNode` is always emitted. For nodes whose state is Stopped, v2
/// doesn't preserve the original registration timestamp — use 0 as the
/// documented placeholder, then emit `StopNode` to drive the node into
/// the Stopped state on apply.
fn from_v2(&self, batch: &mut RecordBatch) {
let registered_time_ns = match &self.state {
NodeStateSnapshot::Running { registered_time_ns } => *registered_time_ns,
NodeStateSnapshot::Stopped { .. } => 0,
};
batch.push(&RegisterNode {
node_catalog_id: self.node_catalog_id.get(),View on GitHub (pinned to 06200ef96b)