{"record":{"id":"9452adb33fe8b8b5","repo":"hashicorp/nomad","slug":"check-s-invalid-check-requires-a-port-but-neithe","errorCode":null,"errorMessage":"Check %s invalid: check requires a port but neither check nor service %+q have a port","messagePattern":"Check (.+?) invalid: check requires a port but neither check nor service %\\+q have a port","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/services.go","lineNumber":845,"sourceCode":"// identity name and service name.\nfunc (s *Service) IdentityHandle(replace envReplacer) *WIHandle {\n\tif s.Identity != nil {\n\t\twi := &WIHandle{\n\t\t\tIdentityName:       s.Identity.Name,\n\t\t\tWorkloadIdentifier: s.Name,\n\t\t\tWorkloadType:       WorkloadTypeService,\n\t\t}\n\t\tif replace != nil {\n\t\t\twi.InterpolatedWorkloadIdentifier = replace(s.Name)\n\t\t}\n\t\treturn wi\n\t}\n\treturn nil\n}\n\nfunc (s *Service) validateCheckPort(c *ServiceCheck) error {\n\tif s.PortLabel == \"\" && c.PortLabel == \"\" && c.RequiresPort() {\n\t\treturn fmt.Errorf(\"Check %s invalid: check requires a port but neither check nor service %+q have a port\", c.Name, s.Name)\n\t}\n\treturn nil\n}\n\n// validateConsulService performs validation on a service which is using the\n// consul provider.\nfunc (s *Service) validateConsulService(mErr *multierror.Error) {\n\t// check checks\n\tfor _, c := range s.Checks {\n\t\t// validate the check port\n\t\tif err := s.validateCheckPort(c); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, err)\n\t\t\tcontinue\n\t\t}\n\n\t\t// TCP checks against a Consul Connect enabled service are not supported\n\t\t// due to the service being bound to the loopback interface inside the\n\t\t// network namespace","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/services.go#L827-L863","documentation":"validateCheckPort fails when a service check RequiresPort() (e.g. tcp, http, grpc checks) but neither the check nor its parent service declares a port. Nomad cannot know which port to probe, so the service definition is rejected. Connect-based checks (which target the proxy) are exempt because they don't need an address.","triggerScenarios":"A service with an empty port label containing a check of type tcp/http/grpc with no check-level port; or a check whose port refers to nothing because the service's port label is empty.","commonSituations":"Defining a health check on a service without assigning a port label; refactoring a service and dropping the port field; templated jobs where the port variable is empty.","solutions":["Set `port` on the check stanza (e.g. port = \"http\").","Set `port` on the parent service stanza so checks inherit it.","If the check targets a Connect sidecar (http/grpc to the proxy), configure it so RequiresPort() is false rather than adding a port."],"exampleFix":"// before\nservice {\n  name = \"web\"\n  check {\n    type = \"tcp\"\n    interval = \"10s\"\n    timeout = \"2s\"\n  }\n}\n// after\nservice {\n  name = \"web\"\n  port = \"http\"\n  check {\n    type = \"tcp\"\n    interval = \"10s\"\n    timeout = \"2s\"\n  }\n}","handlingStrategy":"validation","validationCode":"func checkHasPort(svcPort string, c Check) error {\n  needsPort := c.Type == \"tcp\" || c.Type == \"http\" || c.Type == \"grpc\"\n  if needsPort && svcPort == \"\" && c.PortLabel == \"\" {\n    return fmt.Errorf(\"check %q needs a port on the check or service\", c.Name)\n  }\n  return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always define a port label on services that have tcp/http/grpc checks","Prefer setting port at the service level so all checks inherit it","Lint job files with `nomad job validate` in CI"],"tags":["nomad","service-check","validation","port"],"backgroundTag":"missing-check-port","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"}