{"record":{"id":"83ded6736d2249cc","repo":"vitessio/vitess","slug":"splithostport-can-t-parse-port-q-v","errorCode":null,"errorMessage":"SplitHostPort: can't parse port %q: %v","messagePattern":"SplitHostPort: can't parse port %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/netutil/netutil.go","lineNumber":46,"sourceCode":")\n\n// SplitHostPort is an alternative to net.SplitHostPort that also parses the\n// integer port. In addition, it is more tolerant of improperly escaped IPv6\n// addresses, such as \"::1:456\", which should actually be \"[::1]:456\".\nfunc SplitHostPort(addr string) (string, int, error) {\n\thost, port, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\t// If the above proper parsing fails, fall back on a naive split.\n\t\ti := strings.LastIndex(addr, \":\")\n\t\tif i < 0 {\n\t\t\treturn \"\", 0, fmt.Errorf(\"SplitHostPort: missing port in %q\", addr)\n\t\t}\n\t\thost = addr[:i]\n\t\tport = addr[i+1:]\n\t}\n\tp, err := strconv.ParseUint(port, 10, 16)\n\tif err != nil {\n\t\treturn \"\", 0, fmt.Errorf(\"SplitHostPort: can't parse port %q: %v\", port, err)\n\t}\n\treturn host, int(p), nil\n}\n\n// JoinHostPort is an extension to net.JoinHostPort that also formats the\n// integer port.\nfunc JoinHostPort(host string, port int32) string {\n\treturn net.JoinHostPort(host, strconv.FormatInt(int64(port), 10))\n}\n\n// FullyQualifiedHostname returns the FQDN of the machine.\nfunc FullyQualifiedHostname() (string, error) {\n\t// The machine hostname (which is also returned by os.Hostname()) may not be\n\t// set to the FQDN, but only the first part of it e.g. \"localhost\" instead of\n\t// \"localhost.localdomain\".\n\t// To get the full FQDN, we do the following:\n\n\t// 1. Get the machine hostname. Example: localhost","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/netutil/netutil.go#L28-L64","documentation":"Returned by netutil.SplitHostPort when the port portion of a host:port string cannot be parsed, wrapping the underlying error with the offending port value.","triggerScenarios":"Calling netutil.SplitHostPort with an address whose port portion is invalid, e.g. \"localhost:abc\", \"host:99999\", \"host:\" or an IPv6 bracket form mishandled by the naive split.","commonSituations":"Typos in configured addresses; port fields containing service names like \"mysql\" instead of numbers; truncated config strings; stray characters after the port.","solutions":["Correct the port to a numeric value in 1-65535 range","Check the config source (flag, env, file) for the malformed address","Log the full address being parsed to find where the bad value originates","Use netutil.JoinHostPort with an int port when building addresses"],"exampleFix":"// before\nnetutil.SplitHostPort(\"localhost:mysql\")\n// after\nnetutil.SplitHostPort(\"localhost:3306\")","handlingStrategy":"validation","validationCode":"func validatePort(addr string) error {\n    _, port, ok := strings.Cut(addr, \":\")\n    if !ok {\n        return fmt.Errorf(\"missing port in %q\", addr)\n    }\n    n, err := strconv.Atoi(port)\n    if err != nil || n < 1 || n > 65535 {\n        return fmt.Errorf(\"invalid port %q in %q\", port, addr)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"host, port, err := netutil.SplitHostPort(addr)\nif err != nil {\n    return fmt.Errorf(\"cannot parse address %q: %w\", addr, err)\n}","preventionTips":["Store ports as integers in config and format with JoinHostPort","Reject service names (e.g. \"mysql\") as port values in config validation","Add startup-time validation of all configured addresses"],"tags":["network","address-parsing","invalid-port"],"backgroundTag":"invalid-port-number","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}