hashicorp/nomad · error

wait config min %d is greater than max %d

Error message

wait config min %d is greater than max %d

What it means

WaitConfig.Validate checks the client's wait configuration (used by template/consul-style waiting semantics): if Min is set and Max is also set, Max must be greater than or equal to Min. Otherwise Consul Template cannot form a sane wait interval, so validation fails with this message embedding both values.

Source

Thrown at client/config/config.go:711

}

// Validate returns an error  if the receiver is nil or empty or if Min is greater
// than Max the user specified Max.
func (wc *WaitConfig) Validate() error {
	// If the config is nil or empty return false so that it is never assigned.
	if wc == nil || wc.IsEmpty() {
		return errors.New("wait config is nil or empty")
	}

	// If min is nil, return
	if wc.Min == nil {
		return nil
	}

	// If min isn't nil, make sure Max is less than Min.
	if wc.Max != nil {
		if *wc.Min > *wc.Max {
			return fmt.Errorf("wait config min %d is greater than max %d", *wc.Min, *wc.Max)
		}
	}

	// Otherwise, return nil. Consul Template will set a Max based off of Min.
	return nil
}

// Merge merges two WaitConfigs. The passed instance always takes precedence.
func (wc *WaitConfig) Merge(b *WaitConfig) *WaitConfig {
	if wc == nil {
		return b
	}

	result := *wc
	if b == nil {
		return &result
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Swap or adjust the values so min <= max in the wait config block, e.g. min="5s" max="10s"
  2. If only a min is desired, remove max and let Consul Template derive a default max from min
  3. Check merged config layers for a stray max value and remove the conflicting one
  4. Run validation on the merged config before startup to catch inversions early

Example fix

// before
wait {
  min = "30s"
  max = "10s"
}
// after
wait {
  min = "10s"
  max = "30s"
}
Defensive patterns

Strategy: validation

Validate before calling

func validateWait(min, max *time.Duration) error {
    if min != nil && max != nil && *min > *max {
        return fmt.Errorf("wait min %s > max %s", *min, *max)
    }
    return nil
}

Type guard

func waitBoundsOK(wc *config.WaitConfig) bool {
    return wc == nil || wc.Min == nil || wc.Max == nil || *wc.Min <= *wc.Max
}

Try / catch

if err := wc.Validate(); err != nil {
    if strings.Contains(err.Error(), "min") && strings.Contains(err.Error(), "greater than max") {
        wc.Max = nil // let Consul Template derive max from min
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Calling WaitConfig.Validate (directly or via config validation during agent startup) on a WaitConfig where *Min > *Max, e.g. min=10s max=5s; or after a Merge that combined two configs producing inverted bounds.

Common situations: wait { min = ... max = ... } block in agent config with min larger than max; merging layered config files (base + override) where an override sets a smaller max; refactored code setting fields independently without re-checking ordering.

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.

Related errors


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