{"record":{"id":"aea61ea17b0472fb","repo":"hashicorp/nomad","slug":"service-port-must-be-set-for-mesh-gateway-service","errorCode":null,"errorMessage":"service.port must be set for mesh gateway service","messagePattern":"service\\.port must be set for mesh gateway service","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/job_endpoint_hook_connect.go","lineNumber":363,"sourceCode":"\t\t\tservice.Connect.Gateway.Proxy = gatewayProxy(service.Connect.Gateway, netMode)\n\n\t\t\t// Inject a port whether bridge or host network (if not already set).\n\t\t\t// This port is accessed by the magic of Connect plumbing so it seems\n\t\t\t// reasonable to keep the magic alive here.\n\t\t\tif service.Connect.IsTerminating() && service.PortLabel == \"\" {\n\t\t\t\t// Inject a dynamic port for the terminating gateway.\n\t\t\t\tportLabel := envoy.PortLabel(structs.ConnectTerminatingPrefix, service.Name, \"\")\n\t\t\t\tservice.PortLabel = portLabel\n\t\t\t\tinjectPort(g, portLabel)\n\t\t\t}\n\n\t\t\t// A mesh Gateway will need 2 ports (lan and wan).\n\t\t\tif service.Connect.IsMesh() {\n\n\t\t\t\t// service port is used for mesh gateway wan address - it should\n\t\t\t\t// come from a configured host_network to make sense\n\t\t\t\tif service.PortLabel == \"\" {\n\t\t\t\t\treturn errors.New(\"service.port must be set for mesh gateway service\")\n\t\t\t\t}\n\n\t\t\t\t// Inject a dynamic port for mesh gateway LAN address.\n\t\t\t\tlanPortLabel := envoy.PortLabel(structs.ConnectMeshPrefix, service.Name, \"lan\")\n\t\t\t\tinjectPort(g, lanPortLabel)\n\t\t\t}\n\n\t\t\t// inject the gateway task only if it does not yet already exist\n\t\t\tif !hasGatewayTaskForService(g, service.Name) {\n\t\t\t\tprefix := service.Connect.Gateway.Prefix()\n\n\t\t\t\t// detect whether the group is in host networking mode, which will\n\t\t\t\t// require tweaking the default gateway task config\n\t\t\t\tnetHost := netMode == \"host\"\n\t\t\t\tcustomizedTLS := service.Connect.IsCustomizedTLS()\n\n\t\t\t\ttask := newConnectGatewayTask(prefix, service.Name,\n\t\t\t\t\tservice.GetConsulClusterName(g), groupConnectGuessTaskDriver(g), netHost, customizedTLS)","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/job_endpoint_hook_connect.go#L345-L381","documentation":"A Consul mesh gateway service requires a service port label because that port is used to publish the mesh gateway's WAN address. Nomad's groupConnectHook mutator returns this error when a connect gateway of kind mesh-gateway has an empty service.PortLabel.","triggerScenarios":"Defining a `gateway { mesh { ... } }` in a connect block without setting the service's `port` field, then submitting/mutating the job through groupConnectHook.","commonSituations":"Configuring Consul ingress/terminating gateways works without a service port, so users assume mesh gateways do too; forgetting that mesh gateways additionally need the wan-facing port label.","solutions":["Set `port` on the service that has the mesh gateway block (e.g. pointing to a port on a configured host_network).","Use a port defined with host_network so the WAN address is meaningful.","Re-submit the job after adding the port label."],"exampleFix":"// before\nservice {\n  name = \"mesh-gw\"\n  connect {\n    gateway {\n      mesh {}\n    }\n  }\n}\n\n// after\nservice {\n  name = \"mesh-gw\"\n  port = \"8443\"\n  connect {\n    gateway {\n      mesh {}\n    }\n  }\n}","handlingStrategy":"validation","validationCode":"for _, svc := range group.Services {\n  if svc.Connect != nil && svc.Connect.IsMesh() && svc.PortLabel == \"\" {\n    return fmt.Errorf(\"service %q: mesh gateway requires a port\", svc.Name)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set service.port for mesh gateways","Back the port with a host_network for a meaningful WAN address","Compare with ingress/terminating gateway examples, which differ"],"tags":["nomad","consul-connect","mesh-gateway","job-validation"],"backgroundTag":"consul-connect-mesh-gateway-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"}