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

  1. Quote the value and add a unit: `ttl: "720h"` or `ttl: "30d"`.
  2. Accepted formats: "", "5d", "12h", "30m", "45s", or any Go time.ParseDuration string like "1h30m".
  3. If you meant a numeric-seconds option, use the dedicated field (e.g. ttlStrategy.secondsAfterCompletion) instead of a TTL field.
  4. 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

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


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/51f780f5dc2c55c4. Report an issue: GitHub.