hashicorp/nomad · error

can't specify empty port

Error message

can't specify empty port

What it means

ParsePortRanges rejects a port-range expression that contains an empty token, i.e. a comma-separated segment that is empty or only whitespace before/after splitting on '-'. Nomad uses this when validating reserved host ports in task resources, so empty segments mean a malformed port specification.

Source

Thrown at nomad/structs/funcs.go:508

// maximum number of ports returned to MaxValidPort.
func ParsePortRanges(spec string) ([]uint64, error) {
	count := 0
	parts := strings.Split(spec, ",")

	// Hot path the empty case
	if len(parts) == 1 && parts[0] == "" {
		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:

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove empty segments and stray/trailing commas from the port string (e.g. "22,80" not "22,80,")
  2. Use range syntax only as N-M with N<=M; single ports as bare integers
  3. Check client config 'reserved { ports = "..." }' and any generated config files for interpolation bugs
  4. Validate programmatically with structs.ParsePortRanges(input) before registering the node

Example fix

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

Strategy: validation

Validate before calling

// go: validate port string before node registration
if _, err := structs.ParsePortRanges(portSpec); err != nil {
    return fmt.Errorf("reserved ports invalid (%q): %v", portSpec, err)
}

Try / catch

ports, err := structs.ParsePortRanges(cfg.Reserved.Ports)
if err != nil {
    if strings.Contains(err.Error(), "empty port") {
        return fmt.Errorf("reserved.ports has an empty element: %q", cfg.Reserved.Ports)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ParsePortRanges with input like "22,,80" or a string with a stray comma, or a part that reduces to "" after TrimSpace; IsValidConfig / SetNode invoke it during node registration validation.

Common situations: Hand-written 'reserved' port lists in client config with a trailing comma ('22,80,'); templated config where an empty variable produced an empty element.

Related errors


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