hashicorp/nomad · error

maximum count must be specified and non-negative

Error message

maximum count must be specified and non-negative

What it means

ScalingPolicy.Validate() rejects a policy whose `max` count is negative. The message wording predates the stricter requirement: in practice Max must be a non-negative integer representing the upper scaling bound. Note that Max == 0 also passes this check but is often disallowed elsewhere for horizontal policies.

Source

Thrown at nomad/structs/structs.go:6444

func (p *ScalingPolicy) Validate() error {
	if p == nil {
		return nil
	}

	var mErr multierror.Error

	// Check policy type and target
	if p.Type == "" {
		mErr.Errors = append(mErr.Errors, fmt.Errorf("missing scaling policy type"))
	} else {
		mErr.Errors = append(mErr.Errors, p.validateType().Errors...)
	}

	// Check Min and Max
	if p.Max < 0 {
		mErr.Errors = append(mErr.Errors,
			fmt.Errorf("maximum count must be specified and non-negative"))
	} else if p.Max < p.Min {
		mErr.Errors = append(mErr.Errors,
			fmt.Errorf("maximum count must not be less than minimum count"))
	}

	if p.Min < 0 {
		mErr.Errors = append(mErr.Errors,
			fmt.Errorf("minimum count must be specified and non-negative"))
	}

	return mErr.ErrorOrNil()
}

func (p *ScalingPolicy) validateTargetHorizontal() (mErr multierror.Error) {
	if len(p.Target) == 0 {
		// This is probably not a Nomad horizontal policy
		return
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set `max` to a positive integer greater than or equal to `min` in the scaling block.
  2. If max was intended to be unset, compute a real value instead of using -1.
  3. Run `nomad job validate` to confirm the corrected policy passes.

Example fix

// before
scaling {
  min = 1
  max = -1
}
// after
scaling {
  min = 1
  max = 10
}
Defensive patterns

Strategy: validation

Validate before calling

if policy.Max < 0 {
	return fmt.Errorf("scaling policy max must be non-negative")
}

Prevention

When it happens

Trigger: Submitting a job with `scaling { max = -1 }` or a ScalingPolicy object with a negative Max, e.g. when a default of -1 (meaning unset) is left in place.

Common situations: Using -1 as an 'unset' sentinel from older tooling or API defaults; arithmetic producing a negative max in generated policies; typos like `-10` instead of `10`.

Related errors


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