hashicorp/nomad · error

MaxParallel must be >= 0 but found %d

Error message

MaxParallel must be >= 0 but found %d

What it means

MigrateStrategy.Validate rejects a negative MaxParallel. MaxParallel controls how many allocations may be migrated concurrently during deployments; a negative value is meaningless and indicates a config error. The error is appended to the strategy's multierror and returned during job validation.

Source

Thrown at nomad/structs/structs.go:6840

// DefaultMigrateStrategy is used for backwards compat with pre-0.8 Allocations
// that lack an update strategy.
//
// This function should match its counterpart in api/tasks.go
func DefaultMigrateStrategy() *MigrateStrategy {
	return &MigrateStrategy{
		MaxParallel:     1,
		HealthCheck:     MigrateStrategyHealthChecks,
		MinHealthyTime:  10 * time.Second,
		HealthyDeadline: 5 * time.Minute,
	}
}

func (m *MigrateStrategy) Validate() error {
	var mErr multierror.Error

	if m.MaxParallel < 0 {
		_ = multierror.Append(&mErr, fmt.Errorf("MaxParallel must be >= 0 but found %d", m.MaxParallel))
	}

	switch m.HealthCheck {
	case MigrateStrategyHealthChecks, MigrateStrategyHealthStates:
		// ok
	case "":
		if m.MaxParallel > 0 {
			_ = multierror.Append(&mErr, fmt.Errorf("Missing HealthCheck"))
		}
	default:
		_ = multierror.Append(&mErr, fmt.Errorf("Invalid HealthCheck: %q", m.HealthCheck))
	}

	if m.MinHealthyTime < 0 {
		_ = multierror.Append(&mErr, fmt.Errorf("MinHealthyTime is %s and must be >= 0", m.MinHealthyTime))
	}

	if m.HealthyDeadline < 0 {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set max_parallel to 0 or a positive integer (0 means migrate none during deployment).
  2. If 'unlimited' was intended, use a large positive value; Nomad has no -1 = infinite semantics for max_parallel.
  3. Fix the templating expression producing the negative number.
  4. Validate with `nomad job validate` before submitting.

Example fix

// before
update {
  max_parallel = -1
}
// after
update {
  max_parallel = 1
}
Defensive patterns

Strategy: validation

Validate before calling

func validMaxParallel(m *structs.MigrateStrategy) error {
	if m.MaxParallel < 0 {
		return fmt.Errorf("max_parallel must be >= 0, got %d", m.MaxParallel)
	}
	return nil
}

Type guard

func hasNonNegativeMaxParallel(m *structs.MigrateStrategy) bool {
	return m.MaxParallel >= 0
}

Try / catch

if err := strategy.Validate(); err != nil {
	if strings.Contains(err.Error(), "MaxParallel must be >= 0") {
		// clamp to 0 or positive before resubmit
	}
}

Prevention

When it happens

Trigger: Submitting a job with a task group update block where update.max_parallel is explicitly negative (e.g. max_parallel = -1), typically from templating math or variables that evaluate negative.

Common situations: Templated job files where a computed concurrency value goes negative; mistaken belief that -1 means 'unlimited' (in Nomad, 0 means no migrations during deploy); migration from other orchestrators where -1 signals infinity.

Related errors


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