hashicorp/nomad · error

port must be > 0

Error message

port must be > 0

What it means

ParsePortRanges rejects port 0: a single-token segment parsed successfully but the value is 0, and port 0 is not a reservable host port. Nomad requires explicit positive port numbers when reserving port ranges on a node.

Source

Thrown at nomad/structs/funcs.go:515

		return nil, nil
	}

	ports := []uint64{}
	for _, part := range parts {
		part = strings.TrimSpace(part)
		rangeParts := strings.Split(part, "-")
		l := len(rangeParts)
		switch l {
		case 1:
			if val := rangeParts[0]; val == "" {
				return nil, fmt.Errorf("can't specify empty port")
			} else {
				port, err := strconv.ParseUint(val, 10, 0)
				if err != nil {
					return nil, err
				}
				if port == 0 {
					return nil, fmt.Errorf("port must be > 0")
				}
				if port > MaxValidPort {
					return nil, fmt.Errorf("port must be < %d but found %d", MaxValidPort, port)
				}
				count++
				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)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Replace 0 with an explicit valid port number (1-65535)
  2. If you want dynamic assignment, do not reserve the port — leave it out of reserved.ports and use a dynamic port label in the job
  3. Fix the config source/variable that produced 0 (e.g. unset env var defaulting to 0)
  4. Validate input with structs.ParsePortRanges before applying the node config

Example fix

// before
reserved { ports = "0,22" }
// after
reserved { ports = "8080,22" }
Defensive patterns

Strategy: validation

Validate before calling

// go: reject zero ports before validation pipeline
for _, p := range strings.Split(portSpec, ",") {
    if v, err := strconv.ParseUint(strings.TrimSpace(p), 10, 16); err == nil && v == 0 {
        return errors.New("reserved ports must not include 0")
    }
}

Try / catch

if _, err := structs.ParsePortRanges(portSpec); err != nil {
    if strings.Contains(err.Error(), "port must be > 0") {
        return fmt.Errorf("remove 0 from reserved.ports; use dynamic ports for auto-assign")
    }
    return err
}

Prevention

When it happens

Trigger: ParsePortRanges receives a segment like "0" (or the low end of a range being validated) and port == 0; raised during node SetNode/IsValidConfig validation of the reserved-ports list.

Common situations: Config templating that defaulted a port variable to 0; typos where '0' was written instead of a real port; misunderstanding that port 0 means 'auto-assign' (dynamic ports are handled differently in Nomad).

Related errors


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