{"record":{"id":"787c4fb178c9b975","repo":"micro/go-micro","slug":"unable-to-extract-port-range","errorCode":null,"errorMessage":"unable to extract port range","messagePattern":"unable to extract port range","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/util/net/net.go","lineNumber":54,"sourceCode":"\thost, ports, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// try to extract port range\n\tprange := strings.Split(ports, \"-\")\n\n\t// single port\n\tif len(prange) < 2 {\n\t\treturn fn(addr)\n\t}\n\n\t// we have a port range\n\n\t// extract min port\n\tmin, err := strconv.Atoi(prange[0])\n\tif err != nil {\n\t\treturn nil, errors.New(\"unable to extract port range\")\n\t}\n\n\t// extract max port\n\tmax, err := strconv.Atoi(prange[1])\n\tif err != nil {\n\t\treturn nil, errors.New(\"unable to extract port range\")\n\t}\n\n\t// range the ports\n\tfor port := min; port <= max; port++ {\n\t\t// try bind to host:port\n\t\tln, err := fn(HostPort(host, port))\n\t\tif err == nil {\n\t\t\treturn ln, nil\n\t\t}\n\n\t\t// hit max port\n\t\tif port == max {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/internal/util/net/net.go#L36-L72","documentation":"This error is thrown by util/net.Listen when parsing a user-supplied port range string like \"8000-9000\". The range is split on the separator and each half must parse as an integer via strconv.Atoi; the first half (the minimum port) failed to parse. It is a guard so the pool can know which ports to try binding.","triggerScenarios":"Calling Listen (directly or via a pool that resolves free ports) with a port range whose min portion is not a valid integer, e.g. MIN_PORT unset so the range string is \"-9000\", or \"8000 -9000\" with stray spaces, or a reversed/garbled range like \"x-9000\".","commonSituations":"Misconfigured environment variables or config files for port ranges (MIN_PORT/MAX_PORT); YAML/JSON values quoted or containing whitespace; empty string producing a split with a non-numeric element; platform-specific startup scripts exporting malformed values.","solutions":["Check the port-range value actually passed to Listen and print it before parsing; fix the min portion so it is a plain integer (e.g. \"8000-9000\").","Trim whitespace and remove stray characters before the range reaches Listen.","If the value comes from env/config, validate it with a regex like ^[0-9]+-[0-9]+$ at startup and fail fast with a clear message.","Use named constants or ints in config instead of a raw string to avoid formatting errors."],"exampleFix":"// before\naddr, err := net.Listen(pool, os.Getenv(\"PORT_RANGE\")) // PORT_RANGE=\"8 - 9000\"\n// after\npr := strings.ReplaceAll(os.Getenv(\"PORT_RANGE\"), \" \", \"\") // \"8000-9000\"\nif !regexp.MustCompile(`^[0-9]+-[0-9]+$`).MatchString(pr) {\n    return fmt.Errorf(\"invalid PORT_RANGE: %q\", os.Getenv(\"PORT_RANGE\"))\n}\naddr, err := net.Listen(pool, pr)","handlingStrategy":"validation","validationCode":"func validPortRange(s string) bool {\n    parts := strings.Split(s, \"-\")\n    if len(parts) != 2 { return false }\n    min, err1 := strconv.Atoi(strings.TrimSpace(parts[0]))\n    max, err2 := strconv.Atoi(strings.TrimSpace(parts[1]))\n    return err1 == nil && err2 == nil && min <= max && min > 0 && max <= 65535\n}","typeGuard":"func isPortRange(s string) (min, max int, ok bool) {\n    parts := strings.Split(s, \"-\")\n    if len(parts) != 2 { return 0, 0, false }\n    var e1, e2 error\n    min, e1 = strconv.Atoi(strings.TrimSpace(parts[0]))\n    max, e2 = strconv.Atoi(strings.TrimSpace(parts[1]))\n    return min, max, e1 == nil && e2 == nil\n}","tryCatchPattern":"addr, err := net.Listen(pool, prange)\nif err != nil {\n    if strings.Contains(err.Error(), \"unable to extract port range\") {\n        return fmt.Errorf(\"malformed PORT_RANGE %q: want e.g. 8000-9000\", prange)\n    }\n    return err\n}","preventionTips":["Validate port-range strings with a regex at config-load time","Trim whitespace and normalize dashes (replace unicode – with -) before use","Store port ranges as two integers instead of one string","Log the exact value passed to Listen on failure"],"tags":["configuration","port-range","parse-error","network"],"backgroundTag":"invalid-port-range-config","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}