{"record":{"id":"c743481d8d2a59c4","repo":"hashicorp/nomad","slug":"spread-target-percentage-for-value-q-must-be-betw","errorCode":null,"errorMessage":"Spread target percentage for value %q must be between 0 and 100","messagePattern":"Spread target percentage for value %q must be between 0 and 100","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":10343,"sourceCode":"\tif s.Attribute == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing spread attribute\"))\n\t}\n\tif s.Weight <= 0 || s.Weight > 100 {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Spread block must have a positive weight from 0 to 100\"))\n\t}\n\tseen := make(map[string]struct{})\n\tsumPercent := uint32(0)\n\n\tfor _, target := range s.SpreadTarget {\n\t\t// Make sure there are no duplicates\n\t\t_, ok := seen[target.Value]\n\t\tif !ok {\n\t\t\tseen[target.Value] = struct{}{}\n\t\t} else {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Spread target value %q already defined\", target.Value))\n\t\t}\n\t\tif target.Percent > 100 {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Spread target percentage for value %q must be between 0 and 100\", target.Value))\n\t\t}\n\t\tsumPercent += uint32(target.Percent)\n\t}\n\tif sumPercent > 100 {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Sum of spread target percentages must not be greater than 100%%; got %d%%\", sumPercent))\n\t}\n\treturn mErr.ErrorOrNil()\n}\n\n// SpreadTarget is used to specify desired percentages for each attribute value\ntype SpreadTarget struct {\n\t// Value is a single attribute value, like \"dc1\"\n\tValue string\n\n\t// Percent is the desired percentage of allocs\n\tPercent uint8\n\n\t// Memoized string representation","sourceCodeStart":10325,"sourceCodeEnd":10361,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L10325-L10361","documentation":"Spread.Validate() requires each SpreadTarget's Percent to be at most 100. If any individual target percentage exceeds 100, the job is rejected with 'Spread target percentage for value %q must be between 0 and 100'. (Values below 0 are caught earlier by int min checks/field validation.)","triggerScenarios":"Submitting a job with a spread target whose percent is > 100, e.g. target \"dc1\" { percent = 150 }, via HCL or the /v1/jobs API.","commonSituations":"Confusing percent with weight (weights go to 100 per affinity but sums differ), scripts computing percentages incorrectly, or unit mix-ups (per-mille vs percent).","solutions":["Set each target percent to a value in [0, 100].","Normalize computed percentages so no single target exceeds 100.","Verify the sum of all targets is also <= 100 (a separate check)."],"exampleFix":"// before\nspread {\n  attribute = \"${node.datacenter}\"\n  target \"dc1\" { percent = 150 }\n}\n// after\nspread {\n  attribute = \"${node.datacenter}\"\n  target \"dc1\" { percent = 100 }\n}","handlingStrategy":"validation","validationCode":"if t.Percent > 100 { return fmt.Errorf(\"target %q percent %d exceeds 100\", t.Value, t.Percent) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Bound each target percent to [0,100] in generators","Do not confuse percent with affinity weight scales","Check total sum separately before submission"],"tags":["nomad","spread","percent","job-spec","validation"],"backgroundTag":"invalid-parameter-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"}