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

  1. Correct the TTL value to a non-negative duration (e.g. "1h").
  2. Clamp computed durations with a check: if ttl < 0 { ttl = 0 } before assigning.
  3. 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

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/bf0d30e117ef57ef. Report an issue: GitHub.