hashicorp/nomad · error

port label %q referenced by services %v does not exist

Error message

port label %q referenced by services %v does not exist

What it means

This validation error comes from Nomad's service block validation in Task/group validation. A service (or check) references a port label that is not defined in the task's or group's network resources (or port block) of the job spec. Nomad collects all offending services and reports them together as a multierror before returning validation failure.

Source

Thrown at nomad/structs/structs.go:8615

	for p := range servicePorts {
		keys = append(keys, p)
	}
	sort.Strings(keys)

	// Ensure all ports referenced in services exist.
	for _, servicePort := range keys {
		services := servicePorts[servicePort]
		_, ok := portLabels[servicePort]
		if !ok {
			names := make([]string, 0, len(services))
			for name := range services {
				names = append(names, name)
			}

			// Keep order deterministic
			sort.Strings(names)
			joined := strings.Join(names, ", ")
			err := fmt.Errorf("port label %q referenced by services %v does not exist", servicePort, joined)
			mErr.Errors = append(mErr.Errors, err)
		}
	}

	// Ensure address mode is valid
	return mErr.ErrorOrNil()
}

func (t *Task) Warnings() error {
	var mErr multierror.Error

	// Validate the resources
	if t.Resources != nil && t.Resources.IOPS != 0 {
		mErr.Errors = append(mErr.Errors, fmt.Errorf("IOPS has been deprecated as of Nomad 0.9.0. Please remove IOPS from resource block."))
	}

	if t.Resources != nil && len(t.Resources.Networks) != 0 {
		mErr.Errors = append(mErr.Errors, fmt.Errorf("task network resources have been deprecated as of Nomad 0.12.0. Please configure networking via group network block."))

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add a matching port block to the group network: network { port "http" {} } so the label exists.
  2. Change the service's `port` field to reference an existing port label exactly.
  3. If the service is for Consul Connect, use the connect stanza's implicit port or set `address_mode` correctly for the intended network.
  4. Run `nomad job validate` (or hit the /v1/validate endpoint) before submit to catch the mismatch early.

Example fix

// before
service {
  name = "web"
  port = "http"
}
// (no network port defined)

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

Strategy: validation

Validate before calling

// Pre-check: every service/check port label exists in the group network ports
func checkServicePorts(group map[string][]string /* label -> services */, ports map[string]bool) error {
  for label, svcs := range group {
    if !ports[label] {
      return fmt.Errorf("port label %q referenced by services %v does not exist", label, svcs)
    }
  }
  return nil
}

Prevention

When it happens

Trigger: Submitting a job (jobs/validate or job register) whose `service { port = "http" }` (or a service check port label, or connect sidecar_service port) names a port label absent from the group/task `network { port ... }` blocks. Thrown from the validate path that collects service port labels, sorts them, and appends one error per missing port label.

Common situations: Renaming a port in the network block but not in the service block; copying a service stanza from another job with different port labels; using static vs dynamic port labels incorrectly; typos like "http-port" vs "http"; removing the network block entirely while services remain.

Related errors


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