hashicorp/nomad · error

default_identity_ttl must be greater than 0

Error message

default_identity_ttl must be greater than 0

What it means

During node/agent config validation, an Enforcement/identity config check appends this error to a multierror when DefaultIdentityTTL is less than 1 (i.e. zero or negative). Workload identity tokens need a positive default TTL; the aggregate error is surfaced by Start/monitor (e.g. api/locks.go LockLeaser wraps returned errors in mErr).

Source

Thrown at nomad/structs/node.go:935

// Validate checks that the node introduction configuration is valid.
func (n *NodeIntroductionConfig) Validate() error {

	if n == nil {
		return fmt.Errorf("cannot be empty")
	}

	var mErr *multierror.Error

	switch n.Enforcement {
	case NodeIntroductionEnforcementNone,
		NodeIntroductionEnforcementWarn,
		NodeIntroductionEnforcementStrict:
	default:
		mErr = multierror.Append(mErr, fmt.Errorf("invalid enforcement %q", n.Enforcement))
	}

	if n.DefaultIdentityTTL < 1 {
		mErr = multierror.Append(mErr, errors.New("default_identity_ttl must be greater than 0"))
	}

	if n.MaxIdentityTTL < 1 {
		mErr = multierror.Append(mErr, errors.New("max_identity_ttl must be greater than 0"))
	}

	if n.MaxIdentityTTL < n.DefaultIdentityTTL {
		mErr = multierror.Append(mErr, errors.New(
			"max_identity_ttl must be greater than or equal to default_identity_ttl",
		))
	}

	return mErr.ErrorOrNil()
}

// NodeIntroductionIdentityClaims contains the claims for node introduction.
type NodeIntroductionIdentityClaims struct {
	NodePool string `json:"nomad_node_pool"`

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set default_identity_ttl to a positive duration in the agent config (e.g. default_identity_ttl = "1h").
  2. Check the surrounding multierror output for related errors (max_identity_ttl) and fix all TTL fields at once.
  3. If the value comes from generated config, fix the template/default so an unset value resolves to a valid duration rather than 0.

Example fix

# before
node {
  max_identity_ttl = "12h"
}
# after
node {
  default_identity_ttl = "1h"
  max_identity_ttl = "12h"
}
Defensive patterns

Strategy: validation

Validate before calling

if cfg.DefaultIdentityTTL < 1 {
	return fmt.Errorf("default_identity_ttl must be set to a positive duration, got %d", cfg.DefaultIdentityTTL)
}

Try / catch

if err := ll.Start(ctx, fns...); err != nil {
	if strings.Contains(err.Error(), "default_identity_ttl must be greater than 0") {
		return fmt.Errorf("fix identity TTL config: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Setting `default_identity_ttl` to 0 or a negative duration in agent/node configuration (or the corresponding struct field) and then starting the agent or a component that validates the config, causing Start to return the aggregated multierror.

Common situations: Config stanzas where the TTL was left unset (Go zero value 0) because the operator assumed a built-in default; parsing mistakes that yield 0 (e.g. wrong duration unit or empty string coerced to 0); version upgrades introducing the identity-TTL options with stale config files.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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