hashicorp/nomad · error

error parsing port %q: %v

Error message

error parsing port %q: %v

What it means

After splitting host:port, parseAddress converts the port substring with strconv.Atoi. If the port portion is not a decimal integer (letters, empty after colon, overflow beyond int), the conversion error is wrapped and the address is rejected.

Source

Thrown at command/agent/consul/service_client.go:2180

	result := api.ServiceAddress{}
	addr, portStr, err := net.SplitHostPort(raw)
	// Error message from Go's net/ipsock.go
	if err != nil {
		if !strings.Contains(err.Error(), "missing port in address") {
			return result, fmt.Errorf("error parsing address %q: %v", raw, err)
		}

		// Use the whole input as the address if there wasn't a port.
		if ip := net.ParseIP(raw); ip == nil {
			return result, fmt.Errorf("error parsing address %q: not an IP address", raw)
		}
		addr = raw
	}

	if portStr != "" {
		port, err = strconv.Atoi(portStr)
		if err != nil {
			return result, fmt.Errorf("error parsing port %q: %v", portStr, err)
		}
	}

	result.Address = addr
	result.Port = port
	return result, nil
}

// morph the tagged_addresses map into the structure consul api wants
func parseTaggedAddresses(m map[string]string, port int) (map[string]api.ServiceAddress, error) {
	result := make(map[string]api.ServiceAddress, len(m))
	for k, v := range m {
		sa, err := parseAddress(v, port)
		if err != nil {
			return nil, err
		}
		result[k] = sa
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Use a numeric port between 1-65535 in the address string.
  2. Pass host and port as separate fields (port label resolved by Nomad) instead of embedding in the address.
  3. Fix the template/interpolation that is producing a non-numeric port.

Example fix

// before
service { address = "10.0.0.1:${web_port_label}" }
// after
service { address = "10.0.0.1", port = "web" }
Defensive patterns

Strategy: validation

Validate before calling

func validPortStr(p string) bool {
  n, err := strconv.Atoi(p)
  return err == nil && n >= 1 && n <= 65535
}

Type guard

func isNumericPort(s string) bool {
  n, err := strconv.Atoi(s)
  return err == nil && n > 0 && n <= 65535
}

Try / catch

port, err := strconv.Atoi(portStr)
if err != nil {
  return fmt.Errorf("port must be numeric, got %q", portStr)
}

Prevention

When it happens

Trigger: An address like "10.0.0.1:http" or "10.0.0.1:" or "10.0.0.1:99999999999999" reaching parseAddress, so strconv.Atoi(portStr) fails.

Common situations: Using a service/port name instead of a number in a combined address string; config template leaving an empty port after the colon; oversized numeric port.

Related errors


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