hashicorp/nomad · error

invalid port %q: port label not found or is not numeric

Error message

invalid port %q: port label not found or is not numeric

What it means

GetAddress resolves a service's port label to an advertised port. If the port label is not found in the task's/network's port map AND it is not itself a literal number (strconv.Atoi fails), this error is returned. It signals a misconfiguration in the service or check stanza's port field.

Source

Thrown at client/serviceregistration/address.go:167

		if portLabel == "" {
			return getAddressPort(addressMode, netStatus, 0)
		}

		// If port is a label and is found then return it
		if port, ok := ports.Get(portLabel); ok {
			// Use port.To value unless not set
			if port.To > 0 {
				return getAddressPort(addressMode, netStatus, port.To)
			}

			return getAddressPort(addressMode, netStatus, port.Value)
		}

		// Check if port is a literal number
		port, err := strconv.Atoi(portLabel)
		if err != nil {
			// User likely specified wrong port label here
			return "", 0, fmt.Errorf("invalid port %q: port label not found or is not numeric", portLabel)
		}
		if port <= 0 {
			return "", 0, fmt.Errorf("invalid port: %q: port must be >0", portLabel)
		}

		return getAddressPort(addressMode, netStatus, port)
	default:
		// Shouldn't happen due to validation, but enforce invariants
		return "", 0, fmt.Errorf("invalid address mode %q", addressMode)
	}
}

// getAddressPort is a helper function to return the IPv6 or IPv4 address based on the addressMode
func getAddressPort(addressMode string, netStatus *structs.AllocNetworkStatus, port int) (string, int, error) {
	if addressMode == structs.AddressModeAllocIPv6 {
		return netStatus.AddressIPv6, port, nil
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Fix the port label to match a declared port in the task or group network stanza
  2. Use a numeric literal port (e.g. port = 8080) if advertising a fixed port
  3. Declare the missing port block with the label in the task group network section
  4. Check task vs group level: group-level services can only reference group network port labels

Example fix

// before
service {
  name = "web"
  port = "htpp"
}
// after
service {
  name = "web"
  port = "http"
}
Defensive patterns

Strategy: validation

Validate before calling

labels := collectPortLabels(task, group) // union of task + group network port labels
if !isNumericLiteral(service.PortLabel) && !labels[service.PortLabel] {
    return fmt.Errorf("service %q: port label %q not declared", service.Name, service.PortLabel)
}

Try / catch

ip, port, err := GetAddress(addr, mode, portLabel, networks, dn, ports, netStatus)
if err != nil && strings.Contains(err.Error(), "port label not found") {
    logger.Error("service port label misconfigured", "service", name, "label", portLabel, "err", err)
    return err
}

Prevention

When it happens

Trigger: service { port = "foo" } where "foo" is neither a declared port label in the task's port block nor the group network's port block, nor a numeric literal like "8080". Raised via serviceRegs/generateNomadServiceRegistration when resolving service or check addresses.

Common situations: Typo in port label (e.g. "htpp" vs "http"); referencing a port label defined in a different task; using a label that exists only in a task network when the service is group-level (or vice versa); forgetting to declare a dynamic port before referencing it.

Related errors


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