hashicorp/nomad · error

invalid range: ending value (%v) less than starting (%v) val

Error message

invalid range: ending value (%v) less than starting (%v) value

What it means

ParsePortRanges rejected a port range whose ending port is numerically smaller than its start; ranges like "200-100" cannot produce a valid port set.

Source

Thrown at nomad/structs/funcs.go:539

				if count > MaxValidPort {
					return nil, fmt.Errorf("maximum of %d ports can be reserved", MaxValidPort)
				}
				ports = append(ports, port)
			}
		case 2:
			// We are parsing a range
			start, err := strconv.ParseUint(rangeParts[0], 10, 0)
			if err != nil {
				return nil, err
			}

			end, err := strconv.ParseUint(rangeParts[1], 10, 0)
			if err != nil {
				return nil, err
			}

			if end < start {
				return nil, fmt.Errorf("invalid range: ending value (%v) less than starting (%v) value", end, start)
			}

			// Full range validation is below but prevent creating
			// arbitrarily large arrays here
			if start == 0 {
				return nil, fmt.Errorf("port must be > 0")
			}
			if end > MaxValidPort {
				return nil, fmt.Errorf("port must be < %d but found %d", MaxValidPort, end)
			}
			count += int(end - start)
			if count > MaxValidPort {
				return nil, fmt.Errorf("maximum of %d ports can be reserved", MaxValidPort)
			}
			ports = slices.Grow(ports, int(end-start))
			for i := start; i <= end; i++ {
				ports = append(ports, i)
			}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Fix the range so the start is less than or equal to the end (e.g. "100-200")

Example fix

// before
ports = "500-400"
// after
ports = "400-500"
Defensive patterns

Strategy: validation

Validate before calling

func checkRange(part string) error {
  r := strings.Split(part, "-")
  if len(r) != 2 { return nil }
  s, _ := strconv.Atoi(r[0]); e, _ := strconv.Atoi(r[1])
  if e < s { return fmt.Errorf("range %q: end < start", part) }
  return nil
}

Try / catch

ports, err := structs.ParsePortRanges(spec)
if err != nil && strings.Contains(err.Error(), "less than starting") {
  return fmt.Errorf("fix range order in %q: %w", spec, err)
}

Prevention

When it happens

Trigger: Passing a port range string with start > end, e.g. "500-400", to ParsePortRanges via a Nomad job's network port block.

Common situations: Typo swapping range endpoints when hand-writing HCL/JSON job files, or template variables interpolating in the wrong order.

Related errors


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