hashicorp/nomad · error
TTL must be between 10 seconds and 24 hours
Error message
TTL must be between 10 seconds and 24 hours
What it means
VariableLock.Validate requires the lock TTL to be within [minVariableLockTTL, maxVariableLockTTL] — between 10 seconds and 24 hours per the message. A TTL outside this range (zero, too small, or exceeding 24h) triggers errInvalidTTL. This prevents locks that expire immediately or linger for days.
Source
Thrown at nomad/structs/variables.go:77
// defaultLockTTL is the default value used to maintain a lock before it needs to
// be renewed. The actual value comes from the experience with Consul.
defaultLockTTL = 15 * time.Second
// defaultLockDelay is the default a lock will be blocked after the TTL
// went by without any renews. It is intended to prevent split brain situations.
// The actual value comes from the experience with Consul.
defaultLockDelay = 15 * time.Second
)
var (
errNoPath = errors.New("missing path")
errNoNamespace = errors.New("missing namespace")
errNoLock = errors.New("missing lock ID")
errWildCardNamespace = errors.New("can not target wildcard (\"*\")namespace")
errQuotaExhausted = errors.New("variables are limited to 64KiB in total size")
errNegativeDelayOrTTL = errors.New("Lock delay and TTL must be positive")
errInvalidTTL = errors.New("TTL must be between 10 seconds and 24 hours")
)
// VariableMetadata is the metadata envelope for a Variable, it is the list
// object and is shared data between an VariableEncrypted and a
// VariableDecrypted object.
type VariableMetadata struct {
Namespace string
Path string
// Lock represents a variable which is used for locking functionality.
Lock *VariableLock `json:",omitempty"`
CreateIndex uint64
CreateTime int64
ModifyIndex uint64
ModifyTime int64
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Set TTL to a duration between 10 seconds and 24 hours (e.g. 30 * time.Second).
- Clamp the TTL after parsing: if ttl < 10s use 10s; if ttl > 24h use 24h.
- Check the units of externally supplied TTL values (ms vs ns) and convert to time.Duration correctly.
Example fix
// before
lock := &structs.VariableLock{TTL: 5 * time.Second} // below minVariableLockTTL
// after
lock := &structs.VariableLock{LockDelay: 5 * time.Second, TTL: 30 * time.Second} Defensive patterns
Strategy: validation
Validate before calling
const (
minTTL = 10 * time.Second
maxTTL = 24 * time.Hour
)
func lockTTLValid(ttl time.Duration) bool {
return ttl >= minTTL && ttl <= maxTTL
} Try / catch
if err := lock.Validate(); err != nil {
if strings.Contains(err.Error(), "TTL must be between") {
return fmt.Errorf("lock TTL %s out of range [10s, 24h]", lock.TTL)
}
return err
} Prevention
- Clamp TTL to [10s, 24h] after parsing external input.
- Double-check time.Duration units (ms vs s) when importing TTLs.
- Remember zero-value TTL is invalid; always set it explicitly.
When it happens
Trigger: Setting VariableLock.TTL below 10 seconds (including 0) or above 24 hours and calling Validate; reproduced in TestStructs_Lock_Validate with an out-of-range TTL and LockDelay: 5 * time.Second.
Common situations: Using time.Duration literals in wrong units (e.g. 5 * time.Second when 5 * time.Minute intended); passing a TTL in milliseconds from another system without converting; leaving TTL unset so it is 0.
Related errors
- Lock delay and TTL must be positive
- LockNoPathErr
- multiple lock operations
- default_identity_ttl must be greater than 0
- max_identity_ttl must be greater than 0
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/89e6086fd9cf9cf8.
Report an issue: GitHub.