hashicorp/nomad · error
ttl must be >= 0
Error message
ttl must be >= 0
What it means
WorkloadIdentity.Validate requires TTL >= 0. A negative TTL is nonsensical (identity files/tokens cannot expire in the past by negative duration), so validation flags it as a configuration error, typically the result of a bad duration parse or arithmetic.
Source
Thrown at nomad/structs/workload_id.go:490
if wi.ChangeSignal != "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("can only use change_signal=%q with change_mode=%q",
wi.ChangeSignal, WIChangeModeSignal))
}
case WIChangeModeSignal:
if wi.ChangeSignal == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("change_signal must be specified when using change_mode=%q", WIChangeModeSignal))
}
default:
// Unknown change_mode
mErr.Errors = append(mErr.Errors, fmt.Errorf("invalid change_mode: %s", wi.ChangeMode))
}
if wi.TTL > 0 && (wi.Name == "" || wi.Name == WorkloadIdentityDefaultName) {
mErr.Errors = append(mErr.Errors, fmt.Errorf("ttl for default identity not yet supported"))
}
if wi.TTL < 0 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("ttl must be >= 0"))
}
if wi.Filepath != "" && !wi.File {
mErr.Errors = append(mErr.Errors, fmt.Errorf("file parameter must be true in order to specify filepath"))
}
return mErr.ErrorOrNil()
}
func (wi *WorkloadIdentity) Warnings() error {
if wi == nil {
return fmt.Errorf("must not be nil")
}
var mErr multierror.Error
if n := len(wi.Audience); n == 0 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("identities without an audience are insecure"))View on GitHub (pinned to 482b49bf1a)
Solutions
- Correct the TTL value to a non-negative duration (e.g. "1h").
- Clamp computed durations with a check: if ttl < 0 { ttl = 0 } before assigning.
- Fix the source value (env var, template, config) that produced the negative duration.
Example fix
// before
wi.TTL = target.Sub(time.Now()) // negative if target passed
// after
ttl := target.Sub(time.Now())
if ttl < 0 {
ttl = 0
}
wi.TTL = ttl Defensive patterns
Strategy: validation
Validate before calling
func validateTTLNonNegative(wi *structs.WorkloadIdentity) error {
if wi.TTL < 0 {
return fmt.Errorf("ttl must be >= 0, got %s", wi.TTL)
}
return nil
} Prevention
- Parse TTLs with time.ParseDuration and reject negative results at config load.
- Clamp computed durations to zero before assignment.
- Never compute TTL by subtracting timestamps that may be in the past.
When it happens
Trigger: Setting structs.WorkloadIdentity.TTL to a negative time.Duration, e.g. from a misparsed string like "-1h" or subtracting timestamps before assignment, then calling Validate().
Common situations: Programmatic job generation computing TTL as (target - now) when target is in the past; environment variable or template interpolation yielding a negative duration; unit mistakes like "-5m".
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ttl for default identity not yet supported
- default_identity_ttl must be greater than 0
- max_identity_ttl must be greater than 0
- max_identity_ttl must be greater than or equal to default_id
- TTL must be between 10 seconds and 24 hours
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/bf0d30e117ef57ef.
Report an issue: GitHub.