{"record":{"id":"6f530fb16e25897f","repo":"slackhq/nebula","slug":"appears-to-be-a-range-but-could-not-be-parsed-s","errorCode":null,"errorMessage":"appears to be a range but could not be parsed; `%s`","messagePattern":"appears to be a range but could not be parsed; `(.+?)`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"firewall.go","lineNumber":1079,"sourceCode":"\t\treturn firewall.PortAny, firewall.PortAny, nil\n\t}\n\tif s == \"fragment\" {\n\t\treturn firewall.PortFragment, firewall.PortFragment, nil\n\t}\n\tif !strings.Contains(s, `-`) {\n\t\trPort, err := parsePortValue(\"\", s)\n\t\tif err != nil {\n\t\t\treturn notAPort, notAPort, err\n\t\t}\n\t\treturn rPort, rPort, nil\n\t}\n\n\tsPorts := strings.SplitN(s, `-`, 2)\n\tfor i := range sPorts {\n\t\tsPorts[i] = strings.Trim(sPorts[i], \" \")\n\t}\n\tif len(sPorts) != 2 || sPorts[0] == \"\" || sPorts[1] == \"\" {\n\t\treturn notAPort, notAPort, fmt.Errorf(\"appears to be a range but could not be parsed; `%s`\", s)\n\t}\n\n\tstartPort, err := parsePortValue(\"beginning range \", sPorts[0])\n\tif err != nil {\n\t\treturn notAPort, notAPort, err\n\t}\n\n\tendPort, err := parsePortValue(\"ending range \", sPorts[1])\n\tif err != nil {\n\t\treturn notAPort, notAPort, err\n\t}\n\n\tif startPort == firewall.PortAny {\n\t\tendPort = firewall.PortAny\n\t}\n\n\treturn startPort, endPort, nil\n}","sourceCodeStart":1061,"sourceCodeEnd":1097,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/firewall.go#L1061-L1097","documentation":"parsePort detected a '-' in the port string, so it treats it as a range, but after splitting and trimming, one or both sides are empty (or the split failed), making the range unparseable. Typical culprits are leading/trailing dashes or double dashes, e.g. '-80', '80-', or '80--90'.","triggerScenarios":"Config port value containing '-' that doesn't split into two non-empty tokens, e.g. port: '-100', port: '100-', or port: '10--20', passed through parsePort.","commonSituations":"YAML typos with stray dashes (especially since '-' is also a YAML list indicator); negative port numbers; templates emitting empty endpoints in ranges.","solutions":["Correct the port string to 'start-end' with both endpoints present, e.g. '100-200'","Remove stray or doubled dashes from the value","If a single port is meant, remove the dash entirely"],"exampleFix":"// before\nport: \"-100\"\n// after\nport: \"1-100\"","handlingStrategy":"validation","validationCode":"func checkPortString(s string) error {\n    if strings.Contains(s, \"-\") {\n        parts := strings.SplitN(s, \"-\", 2)\n        if strings.TrimSpace(parts[0]) == \"\" || strings.TrimSpace(parts[1]) == \"\" {\n            return fmt.Errorf(\"malformed port range: %q\", s)\n        }\n    }\n    return nil\n}","typeGuard":"func isWellFormedPortRange(s string) bool {\n    if s == \"any\" || s == \"fragment\" || !strings.Contains(s, \"-\") { return true }\n    p := strings.SplitN(s, \"-\", 2)\n    return strings.TrimSpace(p[0]) != \"\" && strings.TrimSpace(p[1]) != \"\"\n}","tryCatchPattern":"if _, _, err := firewall.ParsePort(s); err != nil {\n    if strings.Contains(err.Error(), \"could not be parsed\") {\n        return fmt.Errorf(\"fix port range syntax in %q: %w\", s, err)\n    }\n    return err\n}","preventionTips":["Quote port range values in YAML so dashes are not misread as list syntax","Always write ranges as 'start-end' with both endpoints present","Validate port strings with a regex like ^\\d+(-\\d+)?$ before loading configs"],"tags":["go","firewall","port-range","parsing"],"backgroundTag":"port-parse-error","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}