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
- Set max_parallel to 0 or a positive integer (0 means migrate none during deployment).
- If 'unlimited' was intended, use a large positive value; Nomad has no -1 = infinite semantics for max_parallel.
- Fix the templating expression producing the negative number.
- 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
- Clamp computed max_parallel to >= 0 in templates.
- Remember 0 (not -1) means 'no migrations during deploy' in Nomad.
- Sanitize external inputs feeding max_parallel.
- Validate update blocks in CI before job submission.
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
- Missing HealthCheck
- Invalid HealthCheck: %q
- MinHealthyTime is %s and must be >= 0
- HealthyDeadline is %s and must be >= 0
- MinHealthyTime must be less than HealthyDeadline
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/1ed62705ae27a7a0.
Report an issue: GitHub.