hashicorp/nomad · error
Port label %s already in use by %s
Error message
Port label %s already in use by %s
What it means
Raised by TaskGroup.validateNetworks when two port entries in the task group's network stanzas share the same label. Nomad tracks port labels in a map; if a label is already claimed ('taskgroup network' by default), the duplicate is rejected so that port-label references (services, checks, connect) stay unambiguous.
Source
Thrown at nomad/structs/structs.go:7337
outer := fmt.Errorf("Task %s validation failed: %v", task.Name, err)
mErr = multierror.Append(mErr, outer)
}
}
return mErr.ErrorOrNil()
}
func (tg *TaskGroup) validateNetworks() error {
var mErr multierror.Error
portLabels := make(map[string]string)
// host_network -> static port tracking
staticPortsIndex := make(map[string]map[int]string)
cniArgKeys := set.New[string](len(tg.Networks))
for _, net := range tg.Networks {
for _, port := range append(net.ReservedPorts, net.DynamicPorts...) {
if other, ok := portLabels[port.Label]; ok {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Port label %s already in use by %s", port.Label, other))
} else {
portLabels[port.Label] = "taskgroup network"
}
if port.Value != 0 {
hostNetwork := port.HostNetwork
if hostNetwork == "" {
hostNetwork = "default"
}
staticPorts, ok := staticPortsIndex[hostNetwork]
if !ok {
staticPorts = make(map[int]string)
}
// static port
if other, ok := staticPorts[port.Value]; ok {
if !port.IgnoreCollision {
err := fmt.Errorf("Static port %d already reserved by %s", port.Value, other)
mErr.Errors = append(mErr.Errors, err)View on GitHub (pinned to 482b49bf1a)
Solutions
- Search the task group's network blocks for the duplicated label named in the error
- Rename one of the duplicate port labels and update any services/tasks referencing it
- Remove redundant port entries if they were accidentally duplicated by templating/merge
- Run `nomad job validate` after editing to confirm all labels are unique
Example fix
// before
network {
port "http" {}
port "http" {}
}
// after
network {
port "http" {}
port "metrics" {}
} Defensive patterns
Strategy: validation
Validate before calling
func uniquePortLabels(tg *api.TaskGroup) error {
seen := map[string]bool{}
for _, n := range tg.Networks {
for _, p := range append(n.ReservedPorts, n.DynamicPorts...) {
if seen[p.Label] { return fmt.Errorf("port label %q duplicated in group %s", p.Label, *tg.Name) }
seen[p.Label] = true
}
}
return nil
} Type guard
func hasUniquePortLabels(tg *api.TaskGroup) bool {
seen := map[string]bool{}
for _, n := range tg.Networks {
for _, p := range append(n.ReservedPorts, n.DynamicPorts...) {
if seen[p.Label] { return false }
seen[p.Label] = true
}
}
return true
} Prevention
- Keep a single canonical network block per task group
- When templating job files, merge network blocks instead of appending
- Grep specs for repeated `port "..."` labels before submit
- Run `nomad job validate` in CI
When it happens
Trigger: A job whose `network { port "http" {} }` (or ReservedPorts/DynamicPorts entries) defines the same port label twice — either within one network block or across multiple network blocks in the same task group.
Common situations: Merging job files or template snippets that each define common labels like "http"/"metrics"; auto-generated specs appending a network stanza when one already exists; copy-pasting a network block into a group that already has ports.
Related errors
- Task group network validation failed: %v
- ErrConnectRequireOneNetwork
- %s: %w: group %q has %d networks
- error parsing reserved_ports: %w
- error parsing reserved_ports for network %q: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ae65e80c395f65d0.
Report an issue: GitHub.