quickwit-oss/quickwit · warning
Invalid time unit: {unit}
Error message
Invalid time unit: {unit} What it means
`parse_duration_nanos` (used by the Jaeger-compatible API to convert duration strings like `"300ms"` into protobuf `Duration`) accepts only the unit suffixes `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`. When the first non-numeric character begins a suffix not in this set (e.g. `"5min"`, `"2sec"`, `"1H"` — matching is case-sensitive), the matcher falls through to the `_` arm and bails. The error is then wrapped by `parse_duration_with_units` into `"Failed to parse duration: ..."`.
Source
Thrown at quickwit/quickwit-serve/src/jaeger_api/parse_duration.rs:55
/// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
fn parse_duration_nanos(input: &str) -> anyhow::Result<i64> {
let mut num_str = String::new();
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() {View on GitHub (pinned to a39730c5cd)
Solutions
- Use a supported unit suffix: ns, us (or µs), ms, s, m, h — e.g. change `30min` to `30m` or `1800s`.
- Convert unsupported units before sending: `2d` → `48h`, `1w` → `168h`.
- Fix case: units are lowercase and case-sensitive (`5S` → `5s`, `5M` is milliseconds not minutes).
- If the value comes from a client tool, configure or patch it to emit Jaeger-spec-compliant durations.
Example fix
// before lookback=2d // after lookback=48h
Defensive patterns
Strategy: validation
Validate before calling
const VALID: &str = "ns|us|µs|ms|s|m|h";
let re = regex::Regex::new(r"^-?\d+(\.\d+)?(ns|us|µs|ms|s|m|h)$").unwrap();
if !re.is_match(duration_str) {
return Err(format!("duration '{}' must match <num><unit> with units ns|us|ms|s|m|h", duration_str));
} Try / catch
match parse_duration_with_units(input) {
Ok(d) => use_duration(d),
Err(e) if e.to_string().contains("Invalid time unit") => {
eprintln!("Unsupported unit in '{}'; use ns/us/ms/s/m/h", input);
default_duration()
}
Err(e) => return Err(e),
} Prevention
- Only emit ns/us/ms/s/m/h unit suffixes in clients targeting the Quickwit Jaeger API.
- Convert day/week durations to hours before sending.
- Remember units are lowercase and case-sensitive (m = minutes, ms = milliseconds).
- Add a client-side regex validation for duration parameters.
When it happens
Trigger: Sending a Jaeger API request (e.g., trace lookup with `lookback=...` or span `duration` min/max parameters) whose duration string ends in an unsupported unit: `min`, `sec`, `d` (days), `w` (weeks), or uppercase variants like `5S` or `5M` (minutes vs milliseconds confusion).
Common situations: A Jaeger client or dashboards emitting Go-style `time.Duration` extended units (days) Quickwit doesn't support; human-written queries using `"30min"` instead of `"30m"`; copy-pasted durations from other systems using different conventions.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
Related errors
- Invalid duration: {num_str}
- 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/5eb874a09968803a.
Report an issue: GitHub.