{"record":{"id":"eaa0b24d067d0d83","repo":"hashicorp/nomad","slug":"maximum-count-must-be-specified-and-non-negative","errorCode":null,"errorMessage":"maximum count must be specified and non-negative","messagePattern":"maximum count must be specified and non-negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":6444,"sourceCode":"\nfunc (p *ScalingPolicy) Validate() error {\n\tif p == nil {\n\t\treturn nil\n\t}\n\n\tvar mErr multierror.Error\n\n\t// Check policy type and target\n\tif p.Type == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"missing scaling policy type\"))\n\t} else {\n\t\tmErr.Errors = append(mErr.Errors, p.validateType().Errors...)\n\t}\n\n\t// Check Min and Max\n\tif p.Max < 0 {\n\t\tmErr.Errors = append(mErr.Errors,\n\t\t\tfmt.Errorf(\"maximum count must be specified and non-negative\"))\n\t} else if p.Max < p.Min {\n\t\tmErr.Errors = append(mErr.Errors,\n\t\t\tfmt.Errorf(\"maximum count must not be less than minimum count\"))\n\t}\n\n\tif p.Min < 0 {\n\t\tmErr.Errors = append(mErr.Errors,\n\t\t\tfmt.Errorf(\"minimum count must be specified and non-negative\"))\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n\nfunc (p *ScalingPolicy) validateTargetHorizontal() (mErr multierror.Error) {\n\tif len(p.Target) == 0 {\n\t\t// This is probably not a Nomad horizontal policy\n\t\treturn\n\t}","sourceCodeStart":6426,"sourceCodeEnd":6462,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L6426-L6462","documentation":"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.","triggerScenarios":"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.","commonSituations":"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`.","solutions":["Set `max` to a positive integer greater than or equal to `min` in the scaling block.","If max was intended to be unset, compute a real value instead of using -1.","Run `nomad job validate` to confirm the corrected policy passes."],"exampleFix":"// before\nscaling {\n  min = 1\n  max = -1\n}\n// after\nscaling {\n  min = 1\n  max = 10\n}","handlingStrategy":"validation","validationCode":"if policy.Max < 0 {\n\treturn fmt.Errorf(\"scaling policy max must be non-negative\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use -1 as an 'unset' sentinel for Max; set a real upper bound.","Compute Max from capacity planning inputs and assert positivity before submission.","Run `nomad job validate` in CI."],"tags":["nomad","scaling-policy","validation"],"backgroundTag":"invalid-numeric-range","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}