hashicorp/nomad · error
client_introduction.default_identity_ttl must be greater one
Error message
client_introduction.default_identity_ttl must be greater one
What it means
Within the client_introduction validation, `default_identity_ttl` must be at least 1 (interpreted as a duration; <1 is nonsensical). Validate() rejects values below 1 before checking max_identity_ttl relationships. This guarantees the agent never configures a zero or negative default identity lifetime.
Source
Thrown at command/agent/config.go:1269
// Validate performs validation on the ClientIntroduction configuration block to
// ensure the values are set correctly for use by the server.
func (c *ClientIntroduction) Validate() error {
if c == nil {
return nil
}
if c.Enforcement == "" {
return errors.New("client_introduction.enforcement must be set")
}
if !slices.Contains(ClientIntroductionEnforcementValues, c.Enforcement) {
return fmt.Errorf("client_introduction.enforcement must be one of %v",
ClientIntroductionEnforcementValues)
}
if c.DefaultIdentityTTL < 1 {
return errors.New("client_introduction.default_identity_ttl must be greater one")
}
if c.MaxIdentityTTL < 1 {
return errors.New("client_introduction.max_identity_ttl must be greater one")
}
if c.MaxIdentityTTL < c.DefaultIdentityTTL {
return errors.New("client_introduction.max_identity_ttl must be greater than default_identity_ttl")
}
return nil
}
// ServerJoin is used in both clients and servers to bootstrap connections to
// servers
type ServerJoin struct {
// StartJoin is a list of addresses to attempt to join when the
// agent starts. If Serf is unable to communicate with any of these
// addresses, then the agent will error and exit.
StartJoin []string `hcl:"start_join"`View on GitHub (pinned to 482b49bf1a)
Solutions
- Set `default_identity_ttl` to a positive duration, e.g. "1h".
- If you intended 'no expiry', use the maximum allowed TTL value instead of 0.
- Verify the duration unit suffix is present in the config so the parsed value is not near-zero.
Example fix
// before
client_introduction {
enforcement = "serve-and-mark"
default_identity_ttl = 0
}
// after
client_introduction {
enforcement = "serve-and-mark"
default_identity_ttl = "1h"
} Defensive patterns
Strategy: validation
Validate before calling
if c := cfg.ClientIntroduction; c != nil && c.DefaultIdentityTTL < 1 {
return errors.New("client_introduction.default_identity_ttl must be >= 1")
} Type guard
func validDefaultTTL(c *ClientIntroduction) bool { return c != nil && c.DefaultIdentityTTL >= 1 } Prevention
- Always include an explicit unit suffix (e.g. "1h") for TTL values.
- Remember 0 does not mean 'unlimited'; use a large TTL for long-lived identities.
- Validate TTLs in CI with the same checks the library performs.
When it happens
Trigger: Config sets `client_introduction.default_identity_ttl` to 0 or a negative number (or the parsed duration is < 1) while the block is present, tripping `if c.DefaultIdentityTTL < 1`.
Common situations: Setting the TTL to 0 intending 'never expire' or 'inherit'; unit/test configs with placeholder values; unit confusion (seconds vs nanoseconds) making an intended positive value parse as near-zero.
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
- client_introduction.max_identity_ttl must be greater one
- client_introduction.max_identity_ttl must be greater than de
- client_introduction.enforcement must be set
- failed to parse config:
- rpc.dial_timeout must be greater than or equal to zero
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ae35b15d58101966.
Report an issue: GitHub.