hashicorp/nomad · error

Spread %d validation failed: %s

Error message

Spread %d validation failed: %s

What it means

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.

Source

Thrown at nomad/structs/structs.go:4805

			mErr.Errors = append(mErr.Errors, fmt.Errorf("System jobs may not have an affinity block"))
		}
	} else {
		for idx, affinity := range j.Affinities {
			if err := affinity.Validate(); err != nil {
				outer := fmt.Errorf("Affinity %d validation failed: %s", idx+1, err)
				mErr.Errors = append(mErr.Errors, outer)
			}
		}
	}

	if j.Type == JobTypeSystem {
		if j.Spreads != nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("System jobs may not have a spread block"))
		}
	} else {
		for idx, spread := range j.Spreads {
			if err := spread.Validate(); err != nil {
				outer := fmt.Errorf("Spread %d validation failed: %s", idx+1, err)
				mErr.Errors = append(mErr.Errors, outer)
			}
		}
	}

	const MaxDescriptionCharacters = 1000
	if j.UI != nil {
		if len(j.UI.Description) > MaxDescriptionCharacters {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("UI description must be under 1000 characters, currently %d", len(j.UI.Description)))
		}
	}

	if j.VersionTag != nil {
		if len(j.VersionTag.Description) > MaxDescriptionCharacters {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Tagged version description must be under 1000 characters, currently %d", len(j.VersionTag.Description)))
		}
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the inner error to find the invalid spread field
  2. Fix the attribute or spread target weights at the given 1-based index
  3. Ensure target percentages are within 0-100 and weights are positive
  4. Use 'nomad job validate' before submission

Example fix

// before
spread {
  attribute = ""
  target "dc1" { percent = 150 }
}
// after
spread {
  attribute = "${node.datacenter}"
  target "dc1" { percent = 50 }
}
Defensive patterns

Strategy: validation

Validate before calling

for i, s := range job.Spreads {
    if err := s.Validate(); err != nil {
        return fmt.Errorf("spread %d invalid: %w", i+1, err)
    }
    for _, t := range s.SpreadTarget {
        if t.Percent < 0 || t.Percent > 100 {
            return fmt.Errorf("spread %d target percent out of range", i+1)
        }
    }
}

Try / catch

if err := job.Validate(); err != nil {
    if strings.Contains(err.Error(), "Spread") {
        return fmt.Errorf("invalid spread config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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