hashicorp/nomad · error
Max Delay cannot be less than Delay %v (got %v)
Error message
Max Delay cannot be less than Delay %v (got %v)
What it means
ReschedulePolicy.Validate() requires MaxDelay >= Delay for non-constant delay functions. A maximum that is smaller than the starting delay is self-contradictory (progression would start above its own ceiling), so the policy is rejected. The message prints (delay, maxDelay) in that argument order.
Source
Thrown at nomad/structs/structs.go:6684
if r.Delay.Nanoseconds() < ReschedulePolicyMinDelay.Nanoseconds() {
_ = multierror.Append(&mErr, fmt.Errorf("Delay cannot be less than %v (got %v)", ReschedulePolicyMinDelay, r.Delay))
delayPreCheck = false
}
// Must use a valid delay function
if !isValidDelayFunction(r.DelayFunction) {
_ = multierror.Append(&mErr, fmt.Errorf("Invalid delay function %q, must be one of %q", r.DelayFunction, RescheduleDelayFunctions))
delayPreCheck = false
}
// Validate MaxDelay if not using linear delay progression
if r.DelayFunction != "constant" {
if r.MaxDelay.Nanoseconds() < ReschedulePolicyMinDelay.Nanoseconds() {
_ = multierror.Append(&mErr, fmt.Errorf("Max Delay cannot be less than %v (got %v)", ReschedulePolicyMinDelay, r.Delay))
delayPreCheck = false
}
if r.MaxDelay < r.Delay {
_ = multierror.Append(&mErr, fmt.Errorf("Max Delay cannot be less than Delay %v (got %v)", r.Delay, r.MaxDelay))
delayPreCheck = false
}
}
// Validate Interval and other delay parameters if attempts are limited
if !r.Unlimited {
if r.Interval.Nanoseconds() < ReschedulePolicyMinInterval.Nanoseconds() {
_ = multierror.Append(&mErr, fmt.Errorf("Interval cannot be less than %v (got %v)", ReschedulePolicyMinInterval, r.Interval))
}
if !delayPreCheck {
// We can't cross validate the rest of the delay params if delayPreCheck fails, so return early
return mErr.ErrorOrNil()
}
crossValidationErr := r.validateDelayParams()
if crossValidationErr != nil {
_ = multierror.Append(&mErr, crossValidationErr)
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Raise max_delay so it is >= delay.
- Lower delay so it fits under the intended max_delay.
- Use delay_function = "constant" if no progression/cap semantics are needed.
Example fix
// before
reschedule {
delay_function = "linear"
delay = "2m"
max_delay = "1m"
}
// after
reschedule {
delay_function = "linear"
delay = "2m"
max_delay = "1h"
} Defensive patterns
Strategy: validation
Validate before calling
if rsl != nil && rsl.DelayFunction != "constant" && rsl.MaxDelay < rsl.Delay {
return fmt.Errorf("max_delay (%v) must be >= delay (%v)", rsl.MaxDelay, rsl.Delay)
} Prevention
- Enforce max_delay >= delay in policy-generation code.
- Update delay and max_delay together when tuning.
- Use constant delay if no ceiling semantics are needed.
When it happens
Trigger: A reschedule block where max_delay < delay, e.g. delay = "2m" with max_delay = "1m" and delay_function != "constant".
Common situations: Tuning delay upward after max_delay was fixed, copy-editing one value without the other, or computed policies where the cap was derived from stale inputs.
Related errors
- Delay cannot be less than %v (got %v)
- Max Delay cannot be less than %v (got %v)
- Reschedule policy has unlimited attempts enabled and a low d
- KillTimeout must be a positive value
- gcs_timeout not a valid duration: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/cf0ef4e45993f273.
Report an issue: GitHub.