hashicorp/nomad · error
Consul Connect services %q and %q in group %q using same add
Error message
Consul Connect services %q and %q in group %q using same address for upstreams (%s)
What it means
Nomad's connect job validation hook (`groupConnectUpstreamsValidate`) builds a listener string (host:port or unix socket path) for every Consul Connect upstream in a task group and rejects duplicates. Two Connect services in the same group declare upstreams that would bind to the exact same local address, so the second would fail at runtime; the job mutator/validator throws this error at `nomad job run`/plan time instead.
Source
Thrown at nomad/job_endpoint_hook_connect.go:587
listeners := make(map[string]string) // address or path-> service
var connectBlockCount int
var hasTproxy bool
for _, service := range services {
if service.Connect != nil {
connectBlockCount++
}
if service.Connect.HasSidecar() && service.Connect.SidecarService.Proxy != nil {
for _, up := range service.Connect.SidecarService.Proxy.Upstreams {
var listener string
if up.LocalBindSocketPath == "" {
listener = net.JoinHostPort(up.LocalBindAddress, strconv.Itoa(up.LocalBindPort))
} else {
listener = up.LocalBindSocketPath
}
if s, exists := listeners[listener]; exists {
return fmt.Errorf(
"Consul Connect services %q and %q in group %q using same address for upstreams (%s)",
service.Name, s, g.Name, listener,
)
}
listeners[listener] = service.Name
}
if tp := service.Connect.SidecarService.Proxy.TransparentProxy; tp != nil {
hasTproxy = true
for _, net := range g.Networks {
if !net.DNS.IsZero() && !tp.NoDNS {
return fmt.Errorf(
"Consul Connect transparent proxy cannot be used with network.dns unless no_dns=true")
}
}
for _, portLabel := range tp.ExcludeInboundPorts {
if !transparentProxyPortLabelValidate(g, portLabel) {
return fmt.Errorf(View on GitHub (pinned to 482b49bf1a)
Solutions
- Give each upstream a distinct local bind port: set `upstream { local_bind_port = <unique-port> }` on one of the conflicting upstreams.
- If both upstreams target the same destination service, remove the duplicate upstream and reference the service once.
- Use distinct `local_bind_socket_path` values if you bind upstreams via unix sockets instead of TCP.
- Keep the default bind address but vary ports, or set a unique `local_bind_address` per upstream.
Example fix
// before
upstream {
destination_name = "count-api"
}
upstream {
destination_name = "count-api2"
# local_bind_port defaults to 8443 too -> collision
}
// after
upstream {
destination_name = "count-api"
}
upstream {
destination_name = "count-api2"
local_bind_port = 9191
} Defensive patterns
Strategy: validation
Validate before calling
// Before submitting, ensure every upstream in each group has a unique bind point.
function validateUpstreamBinds(groups) {
for (const g of groups) {
const seen = new Map();
for (const svc of g.services.filter(s => s.connect)) {
for (const up of svc.connect.sidecar_service?.proxy?.upstreams ?? svc.connect.sidecar_service?.upstreams ?? []) {
const listener = up.local_bind_socket_path ?? `${up.local_bind_address ?? '127.0.0.1'}:${up.local_bind_port ?? 8443}`;
if (seen.has(listener)) throw new Error(`duplicate upstream bind ${listener} in group ${g.name}`);
seen.set(listener, svc.name);
}
}
}
} Prevention
- Always set local_bind_port explicitly on every upstream; never rely on defaults when a group has multiple upstreams.
- Run `nomad job validate <file>` in CI before any `nomad job run`.
- Keep a convention of allocating unique bind port ranges per service in a group.
- When using socket paths, derive them from the service name to guarantee uniqueness.
When it happens
Trigger: Submit a job (nomad job run/plan/validate, or the jobs API Validate endpoint) where a task group contains two `service { connect {} }` blocks whose `upstream` blocks resolve to the identical LocalBindAddress:LocalBindPort or LocalBindSocketPath. This fires in groupConnectUpstreamsValidate when `listeners[listener]` already contains the listener string.
Common situations: Copy-pasting upstream blocks and forgetting to change the default local bind port (8443 or the service port); two upstreams to the same destination service declared under different service blocks, both using the default local bind address; groups with many connect services where each upstream reuses the socket path.
Related errors
- Consul Connect transparent proxy cannot be used with network
- Consul Connect transparent proxy port %q must be numeric or
- Consul Connect transparent proxy requires there is only one
- Check %s invalid: tcp checks are not valid for Connect enabl
- Service %s is Connect Native and requires setting the task
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5d1010c44bb8645d.
Report an issue: GitHub.