ErrLookup › Background articles › "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts
"invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts
"invalid duration", "failed to parse ... as time.Duration", and "invalid timeout format" errors appear when a library receives a duration string — a timeout, interval, TTL, retention window, or schedule — in a format its parser does not accept, most often because a unit is missing ("30" instead of "30s"), the unit is unsupported or misnamed ("1d" in Go code, "30min" instead of "30m"), or the value mixes in syntax from another ecosystem. This article explains why duration parsing fails so often, how each library's accepted grammar differs, and how to write duration values that survive validation.
Distilled from 102 documented records across 32 repositories.
Background
This family lives at a thin but strict boundary: almost every library accepts durations as human-written strings, then immediately converts them to a native numeric type before use — Go's time.ParseDuration (jaeger, fabric, weaviate, dagger, argo-workflows, go-micro, nomad, VictoriaMetrics, k6, siyuan, mcp-toolbox), Rust character-walkers building integer spans (CodeWhale's parse_duration_secs, mise's jiff-based parser), regex-validated settings mungers (puppet's DurationSetting, mastra's parseDuration, oh-my-pi's tmpfilesTtlSeconds), and hand-rolled suffix checkers (deepagents requiring 'm' or 'h', hadoop's lowercase s/m/h/d, litellm's '1h'/'24h'/'7d'/'30d' hint). The parse happens at exactly the moment the value is needed — config load, agent start, function definition, template execution — so failure is always fail-fast, and the raw string lands in the error message alongside a parse cause.
From the caller's side the failure looks absurdly narrow: "500" is rejected because the parser cannot guess whether you meant seconds or milliseconds, "1d" fails in every Go ParseDuration code path because Go has no 'd' unit, and "30min" fails wherever the grammar is a single unit letter or token. The error fires at surprising depths — a channel config block in Fabric (where bad consensus metadata breaks every orderer on the channel), a nomad plugin config, an env var like RUNTIME_OVERRIDES_LOAD_INTERVAL or K6_WEB_DASHBOARD_PERIOD, or a single workflow template field — so the string may come from YAML, HCL, puppet.conf, a cron-ish schedule, or a CLI flag, and the offending value is often templated or interpolated, which is where stray whitespace, empty strings, and raw numbers sneak in.
Most libraries layer additional semantic checks on top of syntax, which widens the family: litellm also rejects non-positive durations ('0h', '-30d') and date-arithmetic overflows; nomad requires start_timeout to be positive; mise rejects negative spans outright; puppet rejects decimals, negatives, and compound strings like '1h30m'; deepagents requires a plain decimal integer before the suffix; CodeWhale rejects components at or above 2^63 and has no millisecond support. Accepted grammars disagree sharply — Go is ns/us/ms/s/m/h with compounds allowed and no 'd'; hadoop allows 'd' but not 'w'; puppet allows 'y' and 'd' but exactly one unit; mastra allows ms/s/m/h/d/w with decimals; k6 and weaviate are pure Go. A value valid in one system is routinely invalid in the next, which is the core reason this family is so well-populated.
Common causes
- Missing unit — a bare number. "30", "500", or "100" is the single most common trigger: the parser refuses to guess seconds versus milliseconds. Affected records include k6 (K6_WEB_DASHBOARD_PERIOD=10), go-micro (--client_request_timeout 500), weaviate, nomad, siyuan (t=30), and hadoop, where the unitless number's last digit is even mistaken for a unit.
- Unsupported 'd' (days) or other units the parser lacks. Go's time.ParseDuration has no days or weeks, so "1d", "1w" fail in argo-workflows timeouts and maxAge, pulumi logs remove --before, jaeger filters, and Fabric; "1w" also fails CodeWhale and oh-my-pi. The universal fix is composing days as "24h" and weeks as "168h" (or "7d" where 'd' is supported).
- Long or invented unit names. "30min", "5mins", "10minutes", "30seconds", "1sec", "5sec", and "1 hour" fail wherever the grammar is a single-letter or single-token unit — puppet, CodeWhale, nomad, k6, mastra ('30min'), oh-my-pi, and mcp-toolbox ('5sec'). Use the exact unit token each library documents, typically one letter.
- Compound or fractional durations. "1h30m" is valid Go syntax but is rejected by puppet (one unit only), deepagents, and oh-my-pi; decimals like "1.5h" fail puppet, CodeWhale (no dot character), and deepagents ('1.5h' fails isdecimal). Convert to the smallest single unit: 1h30m → 90m, 1.5h → 90m or 1h30m depending on the grammar.
- Wrong-ecosystem syntax pasted in. Values copied from cron, systemd, Kubernetes, or ISO-8601 trip parsers: '24h0m0s' into litellm, '1 month'/'monthly', 'PT1H' into dagger, '3:04 PM' into iris's KitchenTime, or JS-style "10sec" into k6. Each parser accepts only its own documented grammar, not a superset.
- Non-positive or semantically invalid values. Several parsers reject parseable-but-meaningless durations: litellm rejects '0h' and '-30d' (reset would be permanently due) and overflow magnitudes like '999999999d'; nomad requires positive start_timeout; mise rejects negative spans ('-30d', '-5m'); mastra rejects '-5s' by regex. Use a real positive duration or omit the setting to fall back to the default.
- Wrong type or contaminated string. Templated or interpolated values arrive with stray whitespace, empty-but-set strings, surrounding quotes, or the wrong type entirely — mlflow rejects ints and timedelta objects where a '<int><unit>' string is expected ('30' instead of '30d'); mastra rejects ' 30s ' with spaces and non-numeric text; deepagents rejects en-dashes and non-breaking spaces that break isdecimal.
What usually fixes it
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
Go deeper
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Documented occurrences
- Invalid budget_duration '{budget_duration}'. Use a format like '1h', '24h', '7d', or '30d'. (BerriAI/litellm)
- invalid duration component: {num_buf:?} (Hmbown/CodeWhale)
- file must begin with '[' (jaegertracing/jaeger)
- failed to parse TickInterval (%s) to time duration (hyperledger/fabric)
- invalid timeout format %w (argoproj/argo-workflows)
- parse RUNTIME_OVERRIDES_LOAD_INTERVAL as time.Duration: %w (weaviate/weaviate)
- failed to parse time to live duration %q: %w (dagger/dagger)
- bad config metadata option ViewChangeResendInterval (hyperledger/fabric)
- Invalid duration format '%{value}' for parameter: %{name} (puppetlabs/puppet)
- failed to parse client_request_timeout: %v (micro/go-micro)
- unrecognised character {ch:?} in duration {s:?} (Hmbown/CodeWhale)
- invalid maxAge: %w (argoproj/argo-workflows)
- invalid value for delay: %w (googleapis/mcp-toolbox)
- kitchen time: convert to time notation first: %w (kataras/iris)
- schedule duration must use 'm' for minutes or 'h' for hours (langchain-ai/deepagents)
- duration must not be negative: {} (jdx/mise)
- INVALID_PARAMETER_VALUE: Invalid value for '{parameter_name}'. Expected a duration in the form `<int><unit>`, where unit is one of 'm', 'h', or 'd' (for example '30d' or '12h'). (mlflow/mlflow)
- Invalid retention duration: "${duration}". Expected a number of milliseconds or a "<number><unit>" string (ms, s, m, h, d, w). (mastra-ai/mastra)
- failed to parse --before as duration or timestamp: %w (pulumi/pulumi)
- cannot parse `staleness_interval: %q`: %w (VictoriaMetrics/VictoriaMetrics)
…and 82 more across the corpus — use search.
Honest provenance: generated on 2026-09-05 from AI-assisted analysis of the linked records. See how records are made.