{"record":{"id":"1ab9322792624776","repo":"hashicorp/nomad","slug":"consul-connect-transparent-proxy-requires-there-is","errorCode":null,"errorMessage":"Consul Connect transparent proxy requires there is only one connect block","messagePattern":"Consul Connect transparent proxy requires there is only one connect block","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/job_endpoint_hook_connect.go","lineNumber":614,"sourceCode":"\t\t\t\thasTproxy = true\n\t\t\t\tfor _, net := range g.Networks {\n\t\t\t\t\tif !net.DNS.IsZero() && !tp.NoDNS {\n\t\t\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\t\t\"Consul Connect transparent proxy cannot be used with network.dns unless no_dns=true\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor _, portLabel := range tp.ExcludeInboundPorts {\n\t\t\t\t\tif !transparentProxyPortLabelValidate(g, portLabel) {\n\t\t\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\t\t\"Consul Connect transparent proxy port %q must be numeric or one of network.port labels\", portLabel)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\tif hasTproxy && connectBlockCount > 1 {\n\t\treturn fmt.Errorf(\"Consul Connect transparent proxy requires there is only one connect block\")\n\t}\n\treturn nil\n}\n\nfunc transparentProxyPortLabelValidate(g *structs.TaskGroup, portLabel string) bool {\n\tif _, err := strconv.ParseUint(portLabel, 10, 16); err == nil {\n\t\treturn true\n\t}\n\n\tfor _, network := range g.Networks {\n\t\tfor _, reservedPort := range network.ReservedPorts {\n\t\t\tif reservedPort.Label == portLabel {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/job_endpoint_hook_connect.go#L596-L632","documentation":"Transparent proxy mode assumes a single Consul Connect sidecar per task group: with more than one connect block, iptables-based interception cannot be attributed consistently. After validating all services, groupConnectUpstreamsValidate checks the accumulated hasTproxy flag against connectBlockCount and fails the job if a transparent proxy is enabled while multiple connect blocks exist.","triggerScenarios":"Job submission where a single task group contains two or more `service { connect { sidecar_service ... } }` blocks and at least one of them sets `proxy.transparent_proxy {}`.","commonSituations":"Scaling an existing group's services to more connect-enabled services after one was migrated to transparent proxy; copy-pasting a connect service block into a group that already uses transparent proxy; misunderstanding that the one-connect-block limit is per task group, not per job.","solutions":["Move the second connect-enabled service into a different task group.","Disable `transparent_proxy {}` (use explicit upstreams) if multiple connect services must share one group.","Consolidate multiple connect services into a single connect block where possible."],"exampleFix":"// before (one group)\ngroup \"web\" {\n  service \"a\" { connect { sidecar_service { proxy { transparent_proxy {} } } } }\n  service \"b\" { connect { sidecar_service {} } }\n}\n// after (split groups)\ngroup \"web-a\" {\n  service \"a\" { connect { sidecar_service { proxy { transparent_proxy {} } } } }\n}\ngroup \"web-b\" {\n  service \"b\" { connect { sidecar_service {} } }\n}","handlingStrategy":"validation","validationCode":"// Transparent proxy requires exactly one connect block per task group.\nfunction validateTproxySingleConnect(group) {\n  const connectCount = (group.services ?? []).filter(s => s.connect).length;\n  const hasTproxy = (group.services ?? []).some(s => s.connect?.sidecar_service?.proxy?.transparent_proxy);\n  if (hasTproxy && connectCount > 1) throw new Error(`group ${group.name}: transparent proxy requires a single connect block`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Design task groups so each transparent-proxy service lives in its own group.","Add a lint rule over HCL/JSON job specs rejecting >1 connect block when transparent_proxy is present.","When adding a new connect service to a group, check existing services for transparent proxy first."],"tags":["consul-connect","transparent-proxy","nomad-job-spec","validation"],"backgroundTag":"incompatible-proxy-dns-config","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}