hashicorp/nomad · error

Nomad can only make %v attempts in %v with initial delay %v,

Error message

Nomad can only make %v attempts in %v with initial delay %v, delay function %q, and delay ceiling %v

What it means

Same viability failure as the constant-delay case, but thrown when delay_function is fibonacci or exponential. viableAttempts() simulates the growing delays (bounded by MaxDelay) and finds that fewer than Attempts retries fit within Interval. The message includes the delay ceiling (MaxDelay) because growth saturation affects the attempt math.

Source

Thrown at nomad/structs/structs.go:6726

	for _, value := range RescheduleDelayFunctions {
		if value == delayFunc {
			return true
		}
	}
	return false
}

func (r *ReschedulePolicy) validateDelayParams() error {
	ok, possibleAttempts, recommendedInterval := r.viableAttempts()
	if ok {
		return nil
	}
	var mErr multierror.Error
	if r.DelayFunction == "constant" {
		_ = multierror.Append(&mErr, fmt.Errorf("Nomad can only make %v attempts in %v with initial delay %v and "+
			"delay function %q", possibleAttempts, r.Interval, r.Delay, r.DelayFunction))
	} else {
		_ = multierror.Append(&mErr, fmt.Errorf("Nomad can only make %v attempts in %v with initial delay %v, "+
			"delay function %q, and delay ceiling %v", possibleAttempts, r.Interval, r.Delay, r.DelayFunction, r.MaxDelay))
	}
	_ = multierror.Append(&mErr, fmt.Errorf("Set the interval to at least %v to accommodate %v attempts", recommendedInterval.Round(time.Second), r.Attempts))
	return mErr.ErrorOrNil()
}

func (r *ReschedulePolicy) viableAttempts() (bool, int, time.Duration) {
	var possibleAttempts int
	var recommendedInterval time.Duration
	valid := true
	switch r.DelayFunction {
	case "constant":
		recommendedInterval = time.Duration(r.Attempts) * r.Delay
		if r.Interval < recommendedInterval {
			possibleAttempts = int(r.Interval / r.Delay)
			valid = false
		}
	case "exponential":

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Increase interval to at least the recommendedInterval value printed by the companion error.
  2. Lower the initial delay and/or MaxDelay so growing delays fit within the interval.
  3. Reduce attempts to a count that fits the simulated delay schedule.
  4. Switch delay_function to "constant" and size interval >= attempts * delay.
  5. Set unlimited: true to bypass viability checks.

Example fix

// before
reschedule {
  attempts      = 5
  interval      = "30m"
  delay         = "10m"
  delay_function = "exponential"
  max_delay     = "1h"
}
// after
reschedule {
  attempts      = 5
  interval      = "8h"
  delay         = "30s"
  delay_function = "exponential"
  max_delay     = "1h"
}
Defensive patterns

Strategy: validation

Validate before calling

func growingDelayViable(p *structs.ReschedulePolicy) bool {
	if p.Unlimited || p.DelayFunction == "constant" {
		return true
	}
	delay, total := p.Delay, time.Duration(0)
	for i := 0; i < p.Attempts; i++ {
		if delay > p.MaxDelay {
			delay = p.MaxDelay
		}
		total += delay
		delay *= 2 // exponential; use fibonacci series for "fibonacci"
	}
	return total <= p.Interval
}

Type guard

func growingDelayFits(p *structs.ReschedulePolicy) bool {
	ok, _, _ := p.ViableAttempts() // or replicate viableAttempts() logic
	return p.Unlimited || ok
}

Try / catch

if err := policy.Validate(); err != nil {
	if strings.Contains(err.Error(), "delay ceiling") {
		// lower delay/max_delay or raise interval before resubmit
	}
}

Prevention

When it happens

Trigger: Submitting a job with reschedule.delay_function = "exponential" or "fibonacci" where the cumulative delays (each capped at MaxDelay) summed over Attempts exceed Interval, with unlimited=false.

Common situations: Large initial delay with exponential growth and a tight interval; MaxDelay set very high so delays keep growing past what the interval can hold; misconfigured policies where interval was chosen for constant-delay semantics.

Related errors


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