hashicorp/nomad · error
Interval must be a non zero value if Attempts > 0
Error message
Interval must be a non zero value if Attempts > 0
What it means
ReschedulePolicy.Validate() in structs.go requires a non-zero Interval whenever Attempts > 0. A reschedule policy that limits attempts must define the window over which they are counted; Attempts > 0 with Interval <= 0 is ambiguous and rejected.
Source
Thrown at nomad/structs/structs.go:6655
func (r *ReschedulePolicy) Enabled() bool {
enabled := r != nil && (r.Attempts > 0 || r.Unlimited)
return enabled
}
// Validate uses different criteria to validate the reschedule policy
// Delay must be a minimum of 1 second
// Delay Ceiling is ignored if Delay Function is "constant"
// Number of possible attempts is validated, given the interval, delay and delay function
func (r *ReschedulePolicy) Validate() error {
if !r.Enabled() {
return nil
}
var mErr multierror.Error
// Check for ambiguous/confusing settings
if r.Attempts > 0 {
if r.Interval <= 0 {
_ = multierror.Append(&mErr, fmt.Errorf("Interval must be a non zero value if Attempts > 0"))
}
if r.Unlimited {
_ = multierror.Append(&mErr, fmt.Errorf("Reschedule Policy with Attempts = %v, Interval = %v, "+
"and Unlimited = %v is ambiguous", r.Attempts, r.Interval, r.Unlimited))
_ = multierror.Append(&mErr, errors.New("If Attempts >0, Unlimited cannot also be set to true"))
}
}
delayPreCheck := true
// Delay should be bigger than the default
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))View on GitHub (pinned to 482b49bf1a)
Solutions
- Set reschedule.interval to a positive duration (e.g. interval = "30m").
- If unlimited rescheduling is desired, set unlimited = true and attempts = 0 instead.
- Run `nomad job validate` before submission to catch the missing field.
Example fix
// before
reschedule {
attempts = 5
delay = "30s"
}
// after
reschedule {
attempts = 5
interval = "1h"
delay = "30s"
} Defensive patterns
Strategy: validation
Validate before calling
if rsl := tg.Reschedule; rsl != nil && rsl.Attempts > 0 && rsl.Interval <= 0 {
return fmt.Errorf("reschedule attempts=%d requires a positive interval", rsl.Attempts)
} Type guard
func rescheduleSane(r *structs.ReschedulePolicy) bool {
return r.Attempts == 0 || r.Interval > 0
} Prevention
- Never set attempts without also setting interval.
- Use NewReschedulePolicy(jobType) defaults for limited policies.
- Template generators should emit interval whenever attempts is emitted.
When it happens
Trigger: A reschedule block (or ReschedulePolicy struct built in code) with attempts set to a positive number but interval left at 0 or negative — often because interval was omitted from the job file or defaulted from the zero-value struct.
Common situations: Hand-written reschedule stanzas missing the interval line, JSON job payloads that omit the field, or constructors that set attempts without interval.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Disconnect cannot be configured with both lost_after and sto
- lost_after cannot be a negative duration
- stop_after cannot be a negative duration
- Missing job ID
- Job ID contains a space
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6cf3ec06d9721354.
Report an issue: GitHub.