quickwit-oss/quickwit · warning
Invalid duration: {num_str}
Error message
Invalid duration: {num_str} What it means
After the unit suffix matches and the numeric part is scaled to nanoseconds, the code checks that the resulting value fits in an `i64`. Here the check is actually on the raw number `num` (before scaling) against `i64::MIN`/`i64::MAX`; if the numeric literal is out of that range the parse bails with the numeric string embedded in the message. It guards against f64/i64 overflow when converting to nanosecond timestamps.
Source
Thrown at quickwit/quickwit-serve/src/jaeger_api/parse_duration.rs:58
for ch in input.trim().chars() {
if ch.is_ascii_digit() || ch == '.' || ch == '-' {
num_str.push(ch);
continue;
}
if ch.is_alphabetic() {
let unit = &input[num_str.len()..];
let num: f64 = num_str.parse()?;
let duration: f64 = match unit {
"ns" => num,
"us" | "µs" => num * 1000.0,
"ms" => num * 1_000_000.0,
"s" => num * 1_000_000_000.0,
"m" => num * 60.0 * 1_000_000_000.0,
"h" => num * 3600.0 * 1_000_000_000.0,
_ => anyhow::bail!("Invalid time unit: {}", unit),
};
if num < i64::MIN as f64 || num > i64::MAX as f64 {
anyhow::bail!("Invalid duration: {}", num_str)
}
return Ok(duration.round() as i64);
} else {
anyhow::bail!("Invalid duration string")
}
}
anyhow::bail!("Invalid duration string")
}
#[cfg(test)]
mod tests {
use crate::jaeger_api::parse_duration::parse_duration_nanos;
#[test]
fn test_parse_duration_nanos() {
// Test valid duration strings
assert_eq!(parse_duration_nanos("300ns").unwrap(), 300);
assert_eq!(parse_duration_nanos("1us").unwrap(), 1000);View on GitHub (pinned to a39730c5cd)
Solutions
- Send a duration whose numeric value fits within ±9.2e18, and preferably a sane duration like `168h` instead of huge second counts.
- Express long ranges with a larger unit to shrink the number (e.g., `9999999999999999s` → `285616h` is still valid, but prefer realistic lookbacks).
- Fix the client code that computes the duration so it clamps or validates the value before formatting.
- Check the request for accidental duplication/mis-scaling of the numeric component.
Example fix
// before
let dur = format!("{}s", millis_since_epoch * 1000);
// after
let dur = format!("{}h", elapsed_hours); Defensive patterns
Strategy: validation
Validate before calling
let num: f64 = num_str.parse()?;
if !num.is_finite() || num < i64::MIN as f64 || num > i64::MAX as f64 {
return Err(format!("duration number '{}' out of i64 range", num_str));
} Try / catch
match parse_duration_with_units(input) {
Ok(d) => use_duration(d),
Err(e) if e.to_string().contains("Invalid duration:") => {
eprintln!("Duration number in '{}' out of range; use a smaller value or larger unit", input);
clamped_duration()
}
Err(e) => return Err(e),
} Prevention
- Clamp or sanitize computed durations client-side before formatting the string.
- Use larger units (h) for long ranges instead of enormous second/millisecond counts.
- Never pass epoch-like magnitudes where a duration is expected.
- Range-check numeric components against i64 bounds in client code.
When it happens
Trigger: Passing an extremely large (or extremely negative) numeric duration to the Jaeger API, e.g. `lookback=99999999999999999999s` or a duration whose magnitude exceeds `i64` (~9.2e18), where `num_str.parse::<f64>()` yields a value outside the `i64` range.
Common situations: Bug in a calling script constructing durations (unbounded multiplication of milliseconds since epoch etc.); a client sending raw epoch-like values as durations; fat-fingered extra digits in a duration.
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
- Invalid time unit: {unit}
- Invalid duration string
- Failed to parse duration: {:?}
- node not found in pending
- OTP logs or traces do not support VRL transforms
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/3f49f1975a0fa65f.
Report an issue: GitHub.