{"record":{"id":"3467486d218bd5ab","repo":"hashicorp/nomad","slug":"s-w-group-q-uses-network-mode-q-must-be-s","errorCode":null,"errorMessage":"%s: %w: group %q uses network mode %q; must be %s","messagePattern":"(.+?): %w: group %q uses network mode %q; must be (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/job_endpoint_hook_connect.go","lineNumber":650,"sourceCode":"}\n\nfunc groupConnectNetworkModeValidate(g *structs.TaskGroup, errorPrefix string, allowHost bool) error {\n\tif nn := len(g.Networks); nn != 1 {\n\t\treturn fmt.Errorf(\"%s: %w: group %q has %d networks\",\n\t\t\terrorPrefix, ErrConnectRequireOneNetwork, g.Name, nn)\n\t}\n\n\tmode := g.Networks[0].Mode\n\tif mode == \"bridge\" || (allowHost && mode == \"host\") || strings.HasPrefix(mode, \"cni/\") {\n\t\treturn nil\n\t}\n\n\t// helpful error message\n\tallowed := `\"bridge\" or \"cni/*\"`\n\tif allowHost {\n\t\tallowed = `\"bridge\", \"host\", or \"cni/*\"`\n\t}\n\treturn fmt.Errorf(\"%s: %w: group %q uses network mode %q; must be %s\",\n\t\terrorPrefix, ErrConnectInvalidNetworkMode, g.Name, mode, allowed)\n}\n\nfunc groupConnectSidecarValidate(g *structs.TaskGroup, s *structs.Service) error {\n\tif err := groupConnectNetworkModeValidate(g, \"connect sidecar\", false); err != nil {\n\t\treturn err\n\t}\n\n\t// We must enforce lowercase characters on group and service names for connect\n\t// sidecar proxies, because Consul assumes this invariant without validating it.\n\t// https://github.com/hashicorp/consul/blob/v1.9.5/command/connect/proxy/proxy.go#L235\n\n\tif s.Name != strings.ToLower(s.Name) {\n\t\treturn fmt.Errorf(\"Consul Connect service name %q in group %q must not contain uppercase characters\", s.Name, g.Name)\n\t}\n\n\tif g.Name != strings.ToLower(g.Name) {\n\t\treturn fmt.Errorf(\"Consul Connect group %q with service %q must not contain uppercase characters\", g.Name, s.Name)","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/job_endpoint_hook_connect.go#L632-L668","documentation":"When a connect-enabled group has exactly one network, its mode must be \"bridge\" (or \"host\" when explicitly allowed, e.g. for expose checks) or a \"cni/...\" prefixed mode. Nomad rejects connect groups whose network mode is anything else, with a message listing the allowed modes for the given context.","triggerScenarios":"Submitting a job where a group's single network block uses mode \"host\" for a connect sidecar (allowHost=false), or a mode like \"mesh-gateway\"/custom non-cni mode, via groupConnectSidecarValidate, groupConnectGatewayValidate, or tgValidateExposeNetworkMode.","commonSituations":"Users setting `mode = \"host\"` on a group network because that is common for non-connect workloads; copy-paste of network stanzas from non-connect jobs; CNI plugin setups where a mode string not starting with \"cni/\" was used; upgrading Nomad and migrating host-networked connect services.","solutions":["Set the group network `mode = \"bridge\"` (the default for connect).","If using a CNI plugin, prefix the mode with \"cni/\" (e.g. mode = \"cni/calico\").","For host networking with connect, only host networking is allowed in the expose-check context; otherwise restructure to use bridge mode."],"exampleFix":"// before\ngroup \"web\" {\n  network {\n    mode = \"host\"\n    port \"http\" {}\n  }\n  service {\n    connect { sidecar_service {} }\n  }\n}\n// after\ngroup \"web\" {\n  network {\n    mode = \"bridge\"\n    port \"http\" {}\n  }\n  service {\n    connect { sidecar_service {} }\n  }\n}","handlingStrategy":"validation","validationCode":"function validateConnectNetworkMode(group, allowHost = false) {\n  const mode = group.networks?.[0]?.mode;\n  const ok = mode === \"bridge\" || (allowHost && mode === \"host\") || String(mode).startsWith(\"cni/\");\n  if (!ok) throw new Error(`group \"${group.name}\" network mode \"${mode}\" not allowed for connect`);\n}","typeGuard":"function isConnectCompatibleMode(mode, allowHost = false) { return mode === \"bridge\" || (allowHost && mode === \"host\") || (typeof mode === 'string' && mode.startsWith('cni/')); }","tryCatchPattern":null,"preventionTips":["Default to `mode = \"bridge\"` for all connect-enabled groups.","Use `cni/<plugin>` modes only when CNI plugins are installed on clients.","Remember host mode is only allowed in expose-check contexts (allowHost=true)."],"tags":["nomad","consul-connect","network-mode","job-validation"],"backgroundTag":"connect-network-mode-invalid","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"}