{"record":{"id":"ee0fafff40d32e3c","repo":"hashicorp/nomad","slug":"consul-connect-must-be-exclusively-native-make-us","errorCode":null,"errorMessage":"Consul Connect must be exclusively native, make use of a sidecar, or represent a Gateway","messagePattern":"Consul Connect must be exclusively native, make use of a sidecar, or represent a Gateway","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/services.go","lineNumber":1361,"sourceCode":"\tif c.HasSidecar() {\n\t\tif c.HasTransparentProxy() {\n\t\t\tif err := c.SidecarService.Proxy.TransparentProxy.Validate(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tcount++\n\t}\n\n\tif c.IsNative() {\n\t\tcount++\n\t}\n\n\tif c.IsGateway() {\n\t\tcount++\n\t}\n\n\tif count != 1 {\n\t\treturn fmt.Errorf(\"Consul Connect must be exclusively native, make use of a sidecar, or represent a Gateway\")\n\t}\n\n\tif c.IsGateway() {\n\t\tif err := c.Gateway.Validate(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Checking against the surrounding task group is validated up at the\n\t// service level or job endpint connect validation hook\n\n\treturn nil\n}\n\n// ConsulSidecarService represents a Consul Connect SidecarService jobspec\n// block.\ntype ConsulSidecarService struct {\n\t// Tags are optional service tags that get registered with the sidecar service","sourceCodeStart":1343,"sourceCodeEnd":1379,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/services.go#L1343-L1379","documentation":"Connect.Validate counts the mutually exclusive Connect modes — IsNative(), a SidecarService, and IsGateway() — and requires exactly one. Setting more than one (or none) makes the connect stanza ambiguous, so it is rejected. If it is a gateway, the gateway block itself is then validated.","triggerScenarios":"A connect stanza with both sidecar_service and native config; a connect stanza with a gateway plus sidecar_service; an empty connect {} block with none of the three.","commonSituations":"Merging service stanzas from different examples; converting a sidecar service to native and leaving leftovers; copy-paste across gateway and non-gateway services.","solutions":["Keep exactly one of: sidecar_service, native, or gateway inside the connect stanza and delete the others.","Remove the connect stanza entirely if the service should not use Connect.","If converting to a gateway service, drop sidecar_service and keep only the gateway block."],"exampleFix":"// before\nconnect {\n  sidecar_service {}\n  gateway {\n    ingress {}\n  }\n}\n// after\nconnect {\n  gateway {\n    ingress {}\n  }\n}","handlingStrategy":"validation","validationCode":"func connectModeCount(c Connect) int {\n  n := 0\n  if c.IsNative() { n++ }\n  if c.SidecarService != nil { n++ }\n  if c.IsGateway() { n++ }\n  return n\n}\nif connectModeCount(conn) != 1 { return errors.New(\"connect must set exactly one of native, sidecar_service, or gateway\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep exactly one Connect mode per service stanza","When converting between modes (sidecar -> native -> gateway), delete old blocks","Avoid merging connect stanzas from different job examples"],"tags":["nomad","consul-connect","validation","config"],"backgroundTag":"connect-mode-ambiguous","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"}