{"record":{"id":"e39017eafcfd79b2","repo":"hashicorp/nomad","slug":"error-parsing-port-label-q-from-service-q-v","errorCode":null,"errorMessage":"error parsing port label %q from service %q: %v","messagePattern":"error parsing port label %q from service %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/consul/service_client.go","lineNumber":1225,"sourceCode":"// Script checks are not supported and will return an error. Registration is\n// asynchronous.\n//\n// Agents will be deregistered when Shutdown is called.\n//\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","sourceCodeStart":1207,"sourceCodeEnd":1243,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/consul/service_client.go#L1207-L1243","documentation":"When registering group-level (agent) services, Nomad expects service.PortLabel to contain 'host:port' (agents do not use port labels directly). net.SplitHostPort failing on the label produces this error, embedding the original parse failure.","triggerScenarios":"Registering a service whose PortLabel is not of the form address:port — e.g. a bare port label like 'http' instead of '${NOMAD_IP_http}:${NOMAD_PORT_http}', or an IPv6 literal without brackets.","commonSituations":"Bridge/network-mode jobs using a plain port label for a group service; interpolation producing an empty string; IPv6 addresses passed unbracketed into SplitHostPort.","solutions":["Set the service's address/port via address_mode or use the interpolated form 'host:port' (e.g. ${NOMAD_IP_http}:${NOMAD_PORT_http}) in PortLabel.","Ensure the interpolation resolves — the referenced port must exist so variables are not empty.","For IPv6, bracket the host part ([fd00::1]:8080) so SplitHostPort succeeds."],"exampleFix":"// before\nservice {\n  name = \"api\"\n  port = \"http\" // bare label for group service\n}\n// after\nservice {\n  name = \"api\"\n  port     = \"http\"\n  provider = \"consul\"\n  address_mode = \"host\" // or use ${NOMAD_IP_http}:${NOMAD_PORT_http}\n}","handlingStrategy":"validation","validationCode":"if _, _, err := net.SplitHostPort(service.PortLabel); err != nil {\n  return fmt.Errorf(\"service %q: PortLabel %q must be host:port\", service.Name, service.PortLabel)\n}","typeGuard":"func isHostPort(label string) bool {\n  _, _, err := net.SplitHostPort(label)\n  return err == nil\n}","tryCatchPattern":null,"preventionTips":["For agent services use host:port, not bare port labels.","Prefer address_mode over manual interpolation where possible.","Bracket IPv6 hosts in address:port strings."],"tags":["consul","service-registration","port-label","nomad"],"backgroundTag":"invalid-host-port-format","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"}