hashicorp/nomad · error

Spread block must have a positive weight from 0 to 100

Error message

Spread block must have a positive weight from 0 to 100

What it means

Spread.Validate() requires Weight to be strictly greater than 0 and at most 100. When Weight is zero, negative, or above 100, this error is appended. The weight determines how strongly spread scoring influences placement relative to other scoring factors, so it must fit in the 1-100 range.

Source

Thrown at nomad/structs/structs.go:10329

	ns.SpreadTarget = CopySliceSpreadTarget(s.SpreadTarget)
	return ns
}

func (s *Spread) String() string {
	if s.str != "" {
		return s.str
	}
	s.str = fmt.Sprintf("%s %s %v", s.Attribute, s.SpreadTarget, s.Weight)
	return s.str
}

func (s *Spread) Validate() error {
	var mErr multierror.Error
	if s.Attribute == "" {
		mErr.Errors = append(mErr.Errors, errors.New("Missing spread attribute"))
	}
	if s.Weight <= 0 || s.Weight > 100 {
		mErr.Errors = append(mErr.Errors, errors.New("Spread block must have a positive weight from 0 to 100"))
	}
	seen := make(map[string]struct{})
	sumPercent := uint32(0)

	for _, target := range s.SpreadTarget {
		// Make sure there are no duplicates
		_, ok := seen[target.Value]
		if !ok {
			seen[target.Value] = struct{}{}
		} else {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Spread target value %q already defined", target.Value))
		}
		if target.Percent > 100 {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Spread target percentage for value %q must be between 0 and 100", target.Value))
		}
		sumPercent += uint32(target.Percent)
	}
	if sumPercent > 100 {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set weight to an integer between 1 and 100, e.g. weight = 50.
  2. If you meant to disable spreading, remove the spread stanza entirely instead of using weight = 0.
  3. If computing weight dynamically, clamp it: w := min(max(w, 1), 100) before constructing Spread.
  4. Validate the job with `nomad job validate` first.

Example fix

// before
spread {
  attribute = "${node.datacenter}"
  weight    = 0
}
// after
spread {
  attribute = "${node.datacenter}"
  weight    = 50
}
Defensive patterns

Strategy: validation

Validate before calling

func validateSpreadWeight(s *structs.Spread) error {
	if s.Weight <= 0 || s.Weight > 100 {
		return fmt.Errorf("spread weight must be in (0, 100], got %d", s.Weight)
	}
	return nil
}

Type guard

func validSpreadWeight(w uint8) bool { return w > 0 && w <= 100 }

Prevention

When it happens

Trigger: Submitting a spread stanza with weight = 0 (or omitted where defaulting didn't apply) or weight = 150; constructing Spread{Attribute: ..., Weight: 0} in Go before Validate.

Common situations: Users thinking 0 weight means 'disabled' and setting weight = 0 (they should delete the stanza instead); percentage confusion where users pass 0-1 floats; programmatic generation defaulting to Go zero-value 0.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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