{"record":{"id":"8fedfbd663decaad","repo":"hashicorp/nomad","slug":"error-parsing-address-q-v","errorCode":null,"errorMessage":"error parsing address %q: %v","messagePattern":"error parsing address %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/consul/service_client.go","lineNumber":2167,"sourceCode":"//\n// If the managed service of the specified id does not exist, or the service does\n// not have a sidecar proxy, nil is returned.\nfunc getNomadSidecar(id string, services map[string]*api.AgentService) *api.AgentService {\n\tif _, exists := services[id]; !exists {\n\t\treturn nil\n\t}\n\n\tsidecarID := id + sidecarSuffix\n\treturn services[sidecarID]\n}\n\nfunc parseAddress(raw string, port int) (api.ServiceAddress, error) {\n\tresult := api.ServiceAddress{}\n\taddr, portStr, err := net.SplitHostPort(raw)\n\t// Error message from Go's net/ipsock.go\n\tif err != nil {\n\t\tif !strings.Contains(err.Error(), \"missing port in address\") {\n\t\t\treturn result, fmt.Errorf(\"error parsing address %q: %v\", raw, err)\n\t\t}\n\n\t\t// Use the whole input as the address if there wasn't a port.\n\t\tif ip := net.ParseIP(raw); ip == nil {\n\t\t\treturn result, fmt.Errorf(\"error parsing address %q: not an IP address\", raw)\n\t\t}\n\t\taddr = raw\n\t}\n\n\tif portStr != \"\" {\n\t\tport, err = strconv.Atoi(portStr)\n\t\tif err != nil {\n\t\t\treturn result, fmt.Errorf(\"error parsing port %q: %v\", portStr, err)\n\t\t}\n\t}\n\n\tresult.Address = addr\n\tresult.Port = port","sourceCodeStart":2149,"sourceCodeEnd":2185,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/consul/service_client.go#L2149-L2185","documentation":"parseAddress splits a raw address string into host and port using net.SplitHostPort. If the string fails to split for any reason other than 'missing port in address' (e.g. too many colons, unbalanced brackets), the underlying error is wrapped and returned, blocking service address registration.","triggerScenarios":"Passing an address with multiple colons without IPv6 brackets (e.g. \"::1:8080\" or \"fd00::1:80\"), or an empty/quoted malformed string, into the address parsing used when building service registrations.","commonSituations":"Advertise address templating producing IPv6 literals without brackets; env var interpolation yielding garbage; copy-pasted address containing scheme like \"http://host:8080\".","solutions":["Wrap IPv6 literals in brackets: [fd00::1]:8080.","Remove any scheme prefix (http://) from the address field.","Provide host and port separately (address + port fields) instead of a combined string.","Quote/escape the address in config so interpolation doesn't inject extra colons."],"exampleFix":"// before\nadvertise { http = \"fd00::1:4646\" }\n// after\nadvertise { http = \"[fd00::1]:4646\" }","handlingStrategy":"validation","validationCode":"func validAddr(s string) bool {\n  if _, _, err := net.SplitHostPort(s); err != nil {\n    return strings.Contains(err.Error(), \"missing port in address\") && net.ParseIP(s) != nil\n  }\n  return true\n}","typeGuard":"func isBracketedIPv6(s string) bool {\n  return strings.HasPrefix(s, \"[\") && strings.Contains(s, \"]\")\n}","tryCatchPattern":"addr, err := parseAddress(raw, port)\nif err != nil {\n  return fmt.Errorf(\"invalid service address %q: %w\", raw, err)\n}","preventionTips":["Always bracket IPv6 literals: [fd00::1]:8080.","Strip scheme prefixes before passing addresses.","Use separate address and port fields instead of combined host:port strings.","Add config linting that rejects unbracketed multi-colon strings."],"tags":["parsing","address","ipv6"],"backgroundTag":"address-parsing-failed","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"}