{"record":{"id":"4583bd0670beee21","repo":"hashicorp/nomad","slug":"error-parsing-port-q-from-service-q-v","errorCode":null,"errorMessage":"error parsing port %q from service %q: %v","messagePattern":"error parsing port %q from service %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/consul/service_client.go","lineNumber":1229,"sourceCode":"//\n// Note: no need to manually plumb Consul namespace into the agent service registration\n// or its check registrations, because the Nomad Client's Consul Client will already\n// have the Nomad Client's Consul Namespace set on startup.\nfunc (c *ServiceClient) RegisterAgent(role string, services []*structs.Service) error {\n\tops := operations{}\n\n\tfor _, service := range services {\n\t\tid := makeAgentServiceID(role, service)\n\n\t\t// Unlike tasks, agents don't use port labels. Agent ports are\n\t\t// stored directly in the PortLabel.\n\t\thost, rawport, err := net.SplitHostPort(service.PortLabel)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing port label %q from service %q: %v\", service.PortLabel, service.Name, err)\n\t\t}\n\t\tport, err := strconv.Atoi(rawport)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing port %q from service %q: %v\", rawport, service.Name, err)\n\t\t}\n\t\tserviceReg := &api.AgentServiceRegistration{\n\t\t\tID:      id,\n\t\t\tName:    service.Name,\n\t\t\tTags:    service.Tags,\n\t\t\tAddress: host,\n\t\t\tPort:    port,\n\t\t\t// This enables the consul UI to show that Nomad registered this service\n\t\t\tMeta: map[string]string{\n\t\t\t\t\"external-source\": \"nomad\",\n\t\t\t},\n\t\t}\n\t\tops.regServices = append(ops.regServices, serviceReg)\n\n\t\t// older agents use SHA-1 hashes as part of the service name instead of\n\t\t// SHA-256, but we can't guarantee they've shutdown gracefully and\n\t\t// deregistered themselves on upgrade. Remove any legacy service IDs\n\t\t// that might be lingering","sourceCodeStart":1211,"sourceCodeEnd":1247,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/consul/service_client.go#L1211-L1247","documentation":"Immediately after successfully splitting the PortLabel, the port component must parse as an integer via strconv.Atoi. If the port substring is non-numeric (bad interpolation, garbage in the label), this error is returned with the raw port, service name, and underlying error.","triggerScenarios":"service.PortLabel contains a host:port whose port field is not a valid integer — e.g. unresolved '${...}' leftovers, letters, or a trailing colon producing an empty rawport.","commonSituations":"Malformed NOMAD_PORT_* interpolation, jobs where the port variable resolves to a name rather than a number, hand-written address:port strings with typos.","solutions":["Ensure the interpolated port variable (e.g. ${NOMAD_PORT_http}) refers to a numeric, allocated port.","Fix or remove malformed characters in the PortLabel so the port segment is a plain integer.","Validate the job spec and inspect the rendered template to confirm resolved values."],"exampleFix":"// before\nport = \"${NOMAD_HOST_IP_http}:${NOMAD_PORT_name}\" // wrong var -> non-numeric port\n// after\nport = \"${NOMAD_IP_http}:${NOMAD_PORT_http}\"","handlingStrategy":"validation","validationCode":"_, rawport, err := net.SplitHostPort(label)\nif err != nil { return err }\nif _, err := strconv.Atoi(rawport); err != nil {\n  return fmt.Errorf(\"port %q is not numeric\", rawport)\n}","typeGuard":"func isNumericPort(raw string) bool {\n  p, err := strconv.Atoi(raw)\n  return err == nil && p > 0 && p < 65536\n}","tryCatchPattern":null,"preventionTips":["Use ${NOMAD_PORT_*} interpolation pointing at numeric ports.","Avoid hand-writing address:port strings in job specs.","Validate rendered job values before registration."],"tags":["consul","service-registration","port","parsing","nomad"],"backgroundTag":"invalid-port-number","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"}