{"record":{"id":"d92ffaaa6c139490","repo":"hashicorp/nomad","slug":"check-q-cannot-use-a-numeric-port-d-without-sett","errorCode":null,"errorMessage":"check %q cannot use a numeric port %d without setting address_mode=\"driver\"","messagePattern":"check %q cannot use a numeric port (.+?) without setting address_mode=\"driver\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8565,"sourceCode":"\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tisNumeric := false\n\t\t\tportNumber, err := strconv.Atoi(effectivePort)\n\t\t\tif err == nil {\n\t\t\t\tisNumeric = true\n\t\t\t}\n\n\t\t\t// Numeric ports are fine for address_mode = \"driver\"\n\t\t\tif check.AddressMode == \"driver\" && isNumeric {\n\t\t\t\tif portNumber <= 0 {\n\t\t\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"check %q has invalid numeric port %d\", check.Name, portNumber))\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif isNumeric {\n\t\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(`check %q cannot use a numeric port %d without setting address_mode=\"driver\"`, check.Name, portNumber))\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// PortLabel must exist, report errors by its parent service\n\t\t\taddServicePort(effectivePort, service.Name)\n\t\t}\n\t}\n\n\t// Get the set of group port labels.\n\tportLabels := make(map[string]struct{})\n\tif len(tgNetworks) > 0 {\n\t\tports := tgNetworks[0].PortLabels()\n\t\tfor portLabel := range ports {\n\t\t\tportLabels[portLabel] = struct{}{}\n\t\t}\n\t}\n\n\t// COMPAT(0.13)","sourceCodeStart":8547,"sourceCodeEnd":8583,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8547-L8583","documentation":"A check whose effective port is numeric (e.g. \"8080\") but whose address_mode is not \"driver\" is rejected: in host/alloc modes the port must be a named label that maps to the host network, because a raw number cannot be resolved to an advertised address. The check must either use a label or opt into driver mode.","triggerScenarios":"Submitting a job where a check's port (own field or inherited service port_label) is a numeric literal while address_mode is unset/default or \"host\"/\"alloc\"; isNumeric is true and address_mode != \"driver\".","commonSituations":"Writing port = \"8080\" instead of a named label like port = \"http\"; migrating from driver-mode configs to host networking; template-generated jobs emitting raw numbers.","solutions":["Define a named port in the group network block (e.g. port \"http\" { to = 8080 }) and set check port = \"http\".","Or set address_mode = \"driver\" on the check if the raw container port is intended.","Update the parent service port_label if the numeric value is inherited from it.","Run `nomad job validate` to catch label/port mismatches before submission."],"exampleFix":"// before\ncheck { name = \"live\"; type = \"http\"; port = \"8080\" }\n\n// after\ncheck { name = \"live\"; type = \"http\"; port = \"http\" }\n# with group:\n# network { port \"http\" {} }","handlingStrategy":"validation","validationCode":"if portStr, err := strconv.Atoi(effectivePort); err == nil && c.AddressMode != \"driver\" {\n  return fmt.Errorf(\"check %q: numeric port %d requires address_mode=driver or a named port label\", c.Name, portStr)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use named port labels for checks in host/alloc address modes","Set address_mode=\"driver\" only when raw container ports are intentional","Keep group network port labels as the single source of truth for ports"],"tags":["nomad","health-check","port","address-mode"],"backgroundTag":"invalid-port-label","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"}