hashicorp/nomad · error
timeout cannot be negative
Error message
timeout cannot be negative
What it means
NewEvalBroker validates that the nack timeout is non-negative before constructing the broker. The nack timeout governs how long a dequeued evaluation can go unacknowledged before being requeued; a negative value is meaningless and is rejected at construction time. This is a programming/configuration error, not a runtime condition.
Source
Thrown at nomad/eval_broker.go:148
// ReadyEvaluations is a list of ready evaluations across multiple jobs. We
// implement the container/heap interface so that this is a priority queue.
type ReadyEvaluations []*structs.Evaluation
// PendingEvaluations is a list of pending evaluations for a given job. We
// implement the container/heap interface so that this is a priority queue.
type PendingEvaluations []*structs.Evaluation
// NewEvalBroker creates a new evaluation broker. This is parameterized
// with the timeout used for messages that are not acknowledged before we
// assume a Nack and attempt to redeliver as well as the deliveryLimit
// which prevents a failing eval from being endlessly delivered. The
// initialNackDelay is the delay before making a Nacked evaluation available
// again for the first Nack and subsequentNackDelay is the compounding delay
// after the first Nack.
func NewEvalBroker(ctx context.Context, timeout, initialNackDelay, subsequentNackDelay time.Duration, deliveryLimit int) (*EvalBroker, error) {
if timeout < 0 {
return nil, fmt.Errorf("timeout cannot be negative")
}
b := &EvalBroker{
nackTimeout: timeout,
deliveryLimit: deliveryLimit,
enabled: false,
enabledNotifier: broker.NewGenericNotifier(ctx),
stats: new(BrokerStats),
evals: make(map[string]int),
jobEvals: make(map[structs.NamespacedID]string),
pending: make(map[structs.NamespacedID]PendingEvaluations),
cancelable: make([]*structs.Evaluation, 0, structs.MaxUUIDsPerWriteRequest),
ready: make(map[string]ReadyEvaluations),
unack: make(map[string]*unackEval),
waiting: make(map[string]chan struct{}),
requeue: make(map[string]*structs.Evaluation),
timeWait: make(map[string]*time.Timer),
initialNackDelay: initialNackDelay,
subsequentNackDelay: subsequentNackDelay,View on GitHub (pinned to 482b49bf1a)
Solutions
- Pass a positive timeout, e.g. time.Minute (the Nomad default is 1 minute).
- Validate the server config value before calling NewServer and reject negatives with a clear message.
- If the intent is 'no nack timeout', pass 0 or the maximum duration, not a negative value.
- Fix parsing of the config value (ensure time.ParseDuration output isn't negated).
Example fix
// before b, err := NewEvalBroker(ctx, -1*time.Second, nackDelay, subDelay, limit) // after timeout := 1 * time.Minute b, err := NewEvalBroker(ctx, timeout, nackDelay, subDelay, limit)
Defensive patterns
Strategy: validation
Validate before calling
if nackTimeout < 0 {
return fmt.Errorf("nack timeout must be >= 0, got %s", nackTimeout)
}
broker, err := NewEvalBroker(ctx, nackTimeout, initDelay, subDelay, limit) Prevention
- Validate durations from config with time.ParseDuration and range checks
- Never use -1 as a sentinel for 'disabled'; use 0 or math.MaxInt64
- Add config linter rules for negative durations
When it happens
Trigger: Calling NewEvalBroker (directly in tests like dummyFSM/testBrokerFromConfig, or via NewServer) with a negative time.Duration for the timeout parameter, typically from a config where TimeoutNack = -1 or an unvalidated user-supplied duration.
Common situations: Operator sets a negative value in server config for evaluation nack timeout; a test harness passes -1 to mean 'disabled'; integer/decimal parsing mistakes turning '-1s' into a negative duration.
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Interval cannot be less than %v (got %v)
- Nomad can only make %v attempts in %v with initial delay %v
- Nomad can only make %v attempts in %v with initial delay %v,
- dynamic workload users disabled
- Job registration, dispatch, and scale are disabled by the sc
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/75d0ee7361bf03a9.
Report an issue: GitHub.