{"record":{"id":"86302d284e354f02","repo":"hashicorp/nomad","slug":"spread-d-validation-failed-s","errorCode":null,"errorMessage":"Spread %d validation failed: %s","messagePattern":"Spread (.+?) validation failed: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":4805,"sourceCode":"\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"System jobs may not have an affinity block\"))\n\t\t}\n\t} else {\n\t\tfor idx, affinity := range j.Affinities {\n\t\t\tif err := affinity.Validate(); err != nil {\n\t\t\t\touter := fmt.Errorf(\"Affinity %d validation failed: %s\", idx+1, err)\n\t\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t\t}\n\t\t}\n\t}\n\n\tif j.Type == JobTypeSystem {\n\t\tif j.Spreads != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"System jobs may not have a spread block\"))\n\t\t}\n\t} else {\n\t\tfor idx, spread := range j.Spreads {\n\t\t\tif err := spread.Validate(); err != nil {\n\t\t\t\touter := fmt.Errorf(\"Spread %d validation failed: %s\", idx+1, err)\n\t\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst MaxDescriptionCharacters = 1000\n\tif j.UI != nil {\n\t\tif len(j.UI.Description) > MaxDescriptionCharacters {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"UI description must be under 1000 characters, currently %d\", len(j.UI.Description)))\n\t\t}\n\t}\n\n\tif j.VersionTag != nil {\n\t\tif len(j.VersionTag.Description) > MaxDescriptionCharacters {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Tagged version description must be under 1000 characters, currently %d\", len(j.VersionTag.Description)))\n\t\t}\n\t}\n","sourceCodeStart":4787,"sourceCodeEnd":4823,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L4787-L4823","documentation":"For non-system jobs, each entry in j.Spreads is validated in Job.Validate(); on failure it is wrapped as 'Spread %d validation failed: %s' (1-based). Spread definitions must target a valid node attribute and weights/targets must be well formed.","triggerScenarios":"Submitting a service/batch job whose Spreads[i].Validate() fails: empty attribute, invalid even/percent weight values in spread targets, or weight outside accepted range.","commonSituations":"Misconfigured spread target percentages that do not sum sensibly, empty attribute string, copy-paste mistakes between constraint/affinity/spread blocks, version drift where a field is unsupported.","solutions":["Read the inner error to find the invalid spread field","Fix the attribute or spread target weights at the given 1-based index","Ensure target percentages are within 0-100 and weights are positive","Use 'nomad job validate' before submission"],"exampleFix":"// before\nspread {\n  attribute = \"\"\n  target \"dc1\" { percent = 150 }\n}\n// after\nspread {\n  attribute = \"${node.datacenter}\"\n  target \"dc1\" { percent = 50 }\n}","handlingStrategy":"validation","validationCode":"for i, s := range job.Spreads {\n    if err := s.Validate(); err != nil {\n        return fmt.Errorf(\"spread %d invalid: %w\", i+1, err)\n    }\n    for _, t := range s.SpreadTarget {\n        if t.Percent < 0 || t.Percent > 100 {\n            return fmt.Errorf(\"spread %d target percent out of range\", i+1)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := job.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"Spread\") {\n        return fmt.Errorf(\"invalid spread config: %w\", err)\n    }\n    return err\n}","preventionTips":["Ensure spread target percents are 0-100","Never leave the spread attribute empty","Test spread configs with 'nomad job validate' before deploy"],"tags":["nomad","job-validation","spread"],"backgroundTag":"nomad-job-validation-failed","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"}