hashicorp/nomad · error

Interval cannot be less than %v (got %v)

Error message

Interval cannot be less than %v (got %v)

What it means

ReschedulePolicy.Validate rejects a reschedule policy whose Interval is below ReschedulePolicyMinInterval. Nomad enforces a minimum interval so that the bounded retry budget (Attempts within Interval) is meaningful; a shorter interval would make the attempt accounting meaningless. The error is appended to a multierror and returned from job/task-group validation, typically surfaced on job submission or plan.

Source

Thrown at nomad/structs/structs.go:6693

	}

	// 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)
		}
	}
	return mErr.ErrorOrNil()
}

func isValidDelayFunction(delayFunc string) bool {
	for _, value := range RescheduleDelayFunctions {
		if value == delayFunc {
			return true
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Increase the reschedule policy interval to at least ReschedulePolicyMinInterval (check the constant in nomad/structs/structs.go; 15m in standard Nomad).
  2. If you truly want unbounded retries, set unlimited: true so Interval is not validated against the minimum.
  3. Validate the reschedule block locally before job submit with the nomad job validate command or structs.ReschedulePolicy.Validate in a unit test.
  4. Fix duration unit typos in the HCL (e.g. meant "1h" not "1m").

Example fix

// before
reschedule {
  attempts = 5
  interval  = "10s"
  delay     = "5s"
  delay_function = "constant"
}
// after
reschedule {
  attempts = 5
  interval  = "15m"
  delay     = "5s"
  delay_function = "constant"
}
Defensive patterns

Strategy: validation

Validate before calling

const MinRescheduleInterval = 15 * time.Minute // ReschedulePolicyMinInterval
func validRescheduleInterval(p *structs.ReschedulePolicy) error {
	if !p.Unlimited && p.Interval < MinRescheduleInterval {
		return fmt.Errorf("interval %v < minimum %v", p.Interval, MinRescheduleInterval)
	}
	return nil
}

Type guard

func hasValidInterval(p *structs.ReschedulePolicy) bool {
	return p.Unlimited || p.Interval >= structs.ReschedulePolicyMinInterval
}

Try / catch

if err := job.Validate(); err != nil {
	var merr *multierror.Error
	if errors.As(err, &merr) {
		for _, e := range merr.Errors {
			if strings.Contains(e.Error(), "Interval cannot be less than") {
				// fix reschedule interval before resubmit
			}
		}
	}
}

Prevention

When it happens

Trigger: Submitting a job whose task_group.reschedule policy has interval set below the minimum (e.g. interval: "10s" when the minimum is 15m) while unlimited is false. Also produced when copying a policy from docs with an interval shorter than the constant ReschedulePolicyMinInterval.

Common situations: Copy-pasting reschedule configs from blog posts or older clusters with aggressive intervals; hand-writing Nomad job specs (HCL/JSON) with typos in duration units (e.g. "5m" vs "5s"); tools generating reschedule blocks programmatically clamping interval too low.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/7f82ea3b2e04971f. Report an issue: GitHub.