hashicorp/nomad · error
Scaling policy invalid: task group count must not be less th
Error message
Scaling policy invalid: task group count must not be less than minimum count in scaling policy
What it means
Appended during task-group validation when the group's Count is below the scaling policy's minimum. The desired count must fit within the policy bounds; the multiregion global region with count 0 is the only exemption.
Source
Thrown at nomad/structs/structs.go:7631
err := tg.Scaling.Validate()
if err != nil {
// prefix scaling policy errors
if me, ok := err.(*multierror.Error); ok {
for _, e := range me.Errors {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Scaling policy invalid: %s", e))
}
}
}
if tg.Scaling.Max < int64(tg.Count) {
mErr.Errors = append(mErr.Errors,
fmt.Errorf("Scaling policy invalid: task group count must not be greater than maximum count in scaling policy"))
}
if int64(tg.Count) < tg.Scaling.Min && !(j.IsMultiregion() && tg.Count == 0 && j.Region == "global") {
mErr.Errors = append(mErr.Errors,
fmt.Errorf("Scaling policy invalid: task group count must not be less than minimum count in scaling policy"))
}
return mErr.ErrorOrNil()
}
// Warnings returns a list of warnings that may be from dubious settings or
// deprecation warnings.
func (tg *TaskGroup) Warnings(j *Job) error {
var mErr multierror.Error
// Validate the update strategy
if u := tg.Update; u != nil {
// Check the counts are appropriate
if tg.Count > 1 && u.MaxParallel > tg.Count && !(j.IsMultiregion() && tg.Count == 0) {
mErr.Errors = append(mErr.Errors,
fmt.Errorf("Update max parallel count is greater than task group count (%d > %d). "+
"A destructive change would result in the simultaneous replacement of all allocations.", u.MaxParallel, tg.Count))
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Raise the group `count` to be >= scaling min
- Lower `min` in the scaling block
- If intentionally scaling to zero, also lower the policy min to 0
Example fix
// before
count = 0
scaling { min = 2 max = 5 }
// after
count = 2
scaling { min = 2 max = 5 } Defensive patterns
Strategy: validation
Validate before calling
if g.Scaling != nil && int64(g.Count) < g.Scaling.Min {
return fmt.Errorf("count %d below scaling.min %d", g.Count, g.Scaling.Min)
} Type guard
func countAboveMin(g *api.TaskGroup) bool {
return g.Scaling == nil || int64(g.Count) >= g.Scaling.Min
} Prevention
- Don't set count=0 on groups with nonzero scaling.min
- Sync scaling.min when intentionally scaling down to zero
- Validate jobs in CI to catch min/count drift
When it happens
Trigger: Submitting a job with `count = N` while the `scaling` block has `min > N` (e.g. count=0, scaling min=2) in a non-exempt (non-multiregion-global) context.
Common situations: Setting count=0 to 'disable' a group that has a scaling policy with a nonzero min; raising min in an autoscaler policy after the job was already written.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Task group scaling policy validation failed: %v
- Scaling policy invalid: %s
- Scaling policy invalid: task group count must not be greater
- ErrConnectRequireOneNetwork
- ErrConnectInvalidNetworkMode
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/8ae58cf6166c0954.
Report an issue: GitHub.