argoproj/argo-workflows · error
invalid TTL
Error message
invalid TTL
What it means
config.TTL's UnmarshalJSON only accepts JSON strings (with units d/h/m/s, empty string, or time.ParseDuration formats). Any non-string JSON value — a bare number, object, array, bool, or null — hits the default branch and returns "invalid TTL" while parsing the controller config (e.g. workflow TTLs / archiving settings).
Source
Thrown at config/ttl.go:58
}
if before, ok := strings.CutSuffix(value, "m"); ok {
minutes, err := strconv.Atoi(before)
*l = TTL(time.Duration(minutes) * time.Minute)
return err
}
if before, ok := strings.CutSuffix(value, "s"); ok {
seconds, err := strconv.Atoi(before)
*l = TTL(time.Duration(seconds) * time.Second)
return err
}
d, err := time.ParseDuration(value)
if err != nil {
return err
}
*l = TTL(d)
return nil
default:
return errors.New("invalid TTL")
}
}
View on GitHub (pinned to 35bff19146)
Solutions
- Quote the value and add a unit: `ttl: "720h"` or `ttl: "30d"`.
- Accepted formats: "", "5d", "12h", "30m", "45s", or any Go time.ParseDuration string like "1h30m".
- If you meant a numeric-seconds option, use the dedicated field (e.g. ttlStrategy.secondsAfterCompletion) instead of a TTL field.
- Validate the controller ConfigMap by restarting the controller and checking logs for config parse errors.
Example fix
# before
workflowDefaults: {}
archive:
ttl: 30
# after
archive:
ttl: "30d" Defensive patterns
Strategy: validation
Validate before calling
// validate TTL config value before applying
ttl, ok := v.(string)
if !ok {
return fmt.Errorf("TTL must be a string like \"30d\", \"12h\", \"30m\", got %T", v)
}
if _, err := time.ParseDuration(strings.TrimSuffix(ttl, "d") + "h"); err != nil && !strings.HasSuffix(ttl, "d") {
return fmt.Errorf("invalid TTL duration %q", ttl)
} Type guard
func isStringTTL(v any) (string, bool) {
s, ok := v.(string)
return s, ok
} Prevention
- Always quote TTL values in YAML/JSON config: "30d", "12h"
- Never use bare numbers for TTL fields
- Remember supported units: d, h, m, s, or Go duration strings
- Validate the controller ConfigMap after edits before rollout
When it happens
Trigger: Setting a TTL field in the workflow-controller ConfigMap as a number (e.g. `ttlStrategy: {secondsSinceCompletion: ...}` is fine, but a TTL field like `ttl: 30` or `"ttl": {"seconds": 30}`) instead of a quoted duration string like "30m", "24h", or "5d".
Common situations: Users writing YAML that a YAML parser turns into an int (unquoted `ttl: 30`); copying configs between features where one expects a number (secondsSinceCompletion) and this one expects a string; upgrading and moving a TTL field into config where TTL unmarshalling applies.
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
- json: unknown field "%s"
- Error in Unmarshalling after merge the patch
- --wait cannot be combined with --server-dry-run
- --dry-run should have an output option
- --dry-run cannot be combined with --server-dry-run
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/51f780f5dc2c55c4.
Report an issue: GitHub.