{"record":{"id":"98a0f2669d9f761e","repo":"grpc/grpc-go","slug":"invalid-target-address-v-error-info-v","errorCode":null,"errorMessage":"invalid target address %v, error info: %v","messagePattern":"invalid target address (.+?), error info: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/resolver/dns/dns_resolver.go","lineNumber":416,"sourceCode":"\tif host, port, err = net.SplitHostPort(target); err == nil {\n\t\tif port == \"\" {\n\t\t\t// If the port field is empty (target ends with colon), e.g. \"[::1]:\",\n\t\t\t// this is an error.\n\t\t\treturn \"\", \"\", internal.ErrEndsWithColon\n\t\t}\n\t\t// target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port\n\t\tif host == \"\" {\n\t\t\t// Keep consistent with net.Dial(): If the host is empty, as in \":80\",\n\t\t\t// the local system is assumed.\n\t\t\thost = \"localhost\"\n\t\t}\n\t\treturn host, port, nil\n\t}\n\tif host, port, err = net.SplitHostPort(target + \":\" + defaultPort); err == nil {\n\t\t// target doesn't have port\n\t\treturn host, port, nil\n\t}\n\treturn \"\", \"\", fmt.Errorf(\"invalid target address %v, error info: %v\", target, err)\n}\n\ntype rawChoice struct {\n\tClientLanguage *[]string        `json:\"clientLanguage,omitempty\"`\n\tPercentage     *int             `json:\"percentage,omitempty\"`\n\tClientHostName *[]string        `json:\"clientHostName,omitempty\"`\n\tServiceConfig  *json.RawMessage `json:\"serviceConfig,omitempty\"`\n}\n\nfunc containsString(a *[]string, b string) bool {\n\tif a == nil {\n\t\treturn true\n\t}\n\tfor _, c := range *a {\n\t\tif c == b {\n\t\t\treturn true\n\t\t}\n\t}","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/resolver/dns/dns_resolver.go#L398-L434","documentation":"Returned by the dns resolver's parseTarget as the final fallback when every parsing attempt fail: the target is not a bare IP, not a valid host:port, and joining it with the default port also fails. This is the catch-all for unparseable target strings passed to the dns resolver.","triggerScenarios":"Targets with illegal characters for both SplitHostPort and JoinHostPort (e.g. unbracketed raw IPv6 like \"::1:443\", targets containing spaces or slashes in the host). It is the inner error returned from dnsBuilder.Build and propagated to the caller as a dial failure.","commonSituations":"Passing an unbracketed IPv6 address (must be \"[::1]:443\"); copy-paste of a full URL (\"https://host\") as the target; target containing a path or query fragment.","solutions":["Bracket IPv6 literals: \"[2001:db8::1]:443\".","Pass only host or host:port to the dns target, not a full URL; strip scheme/path.","Use the dns:/// authority form consistently: \"dns:///host:port\".","Validate the target format before dialing."],"exampleFix":"// before\nconn, _ := grpc.Dial(\"::1:443\", ...)        // unparseable\nconn, _ := grpc.Dial(\"https://host:443\", ...) // scheme leaks in\n// after\nconn, _ := grpc.Dial(\"dns:///[::1]:443\", ...)\nconn, _ := grpc.Dial(\"dns:///host:443\", ...)","handlingStrategy":"validation","validationCode":"// Normalize target before dialing.\nfunc normalizeTarget(t string) string {\n    t = strings.TrimSpace(t)\n    t = strings.TrimPrefix(t, \"https://\")\n    t = strings.TrimPrefix(t, \"http://\")\n    if strings.Count(t, \":\") > 1 && !strings.HasPrefix(t, \"[\") {\n        // Looks like bare IPv6; bracket it.\n        host, port, err := net.SplitHostPort(t)\n        if err == nil { t = net.JoinHostPort(host, port) }\n    }\n    return \"dns:///\" + t\n}","typeGuard":"func looksLikeValidDnsTarget(t string) bool {\n    ep := strings.TrimPrefix(t, \"dns:///\")\n    if ep == \"\" { return false }\n    if _, err := netip.ParseAddr(ep); err == nil { return true }\n    _, _, err := net.SplitHostPort(ep)\n    return err == nil\n}","tryCatchPattern":"conn, err := grpc.Dial(target, ...)\nif err != nil && strings.Contains(err.Error(), \"invalid target address\") {\n    conn, err = grpc.Dial(normalizeTarget(target), ...)\n}","preventionTips":["Always bracket IPv6 literals: [::1]:443.","Use the dns:///authority/host:port URI form consistently.","Strip scheme/path from URLs before passing them as targets."],"tags":["grpc","resolver","dns","target-uri","ipv6","validation"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}