{"record":{"id":"ebeb661f4c4ede36","repo":"shadow1ng/fscan","slug":"parser-invalid-start-ip","errorCode":null,"errorMessage":"parser_invalid_start_ip","messagePattern":"parser_invalid_start_ip","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/parsers/host_iterator.go","lineNumber":354,"sourceCode":"\tend := start + uint32(size-1)\n\tif size > 2 {\n\t\tstart++\n\t\tend--\n\t}\n\treturn &cidrHostSource{current: start, end: end}, nil\n}\n\nfunc newRangeHostSource(rangeStr string) (hostSource, error) {\n\tparts := strings.Split(rangeStr, \"-\")\n\tif len(parts) != 2 {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_ip_range_fmt\", rangeStr))\n\t}\n\n\tstartIPStr := strings.TrimSpace(parts[0])\n\tendIPStr := strings.TrimSpace(parts[1])\n\tstartIP := net.ParseIP(startIPStr)\n\tif startIP == nil {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_start_ip\", startIPStr))\n\t}\n\n\tif len(endIPStr) < 4 || !strings.Contains(endIPStr, \".\") {\n\t\tendNum, err := strconv.Atoi(endIPStr)\n\t\tif err != nil || endNum > 255 {\n\t\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_ip_end_val\", endIPStr))\n\t\t}\n\t\tparts := strings.Split(startIPStr, \".\")\n\t\tif len(parts) != 4 {\n\t\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_ip_fmt\", startIPStr))\n\t\t}\n\t\tparts[3] = strconv.Itoa(endNum)\n\t\tendIPStr = strings.Join(parts, \".\")\n\t}\n\n\tstart, ok := ipToUint32(startIP)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.GetText(\"parser_ipv4_only\"))","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/common/parsers/host_iterator.go#L336-L372","documentation":"The start portion of an IP range string failed net.ParseIP. newRangeHostSource trims the text before the dash and requires it to be a valid IP literal; anything else (hostname, octet out of range like 300.1.1.1, empty string) yields this message naming the bad start value.","triggerScenarios":"addRange/newHostSource with \"example.com-10.0.0.5\", \"300.0.0.1-10.0.0.2\", \"-10.0.0.5\", or any non-IP text left of the dash.","commonSituations":"Users entering hostnames instead of IPs; mistyped octets (e.g. 192.168.1.256); whitespace or invisible characters from YAML/CSV fields that TrimSpace does not remove (e.g. NBSP).","solutions":["Correct the start IP so net.ParseIP accepts it, e.g. \"192.168.1.10-192.168.1.20\".","Validate with net.ParseIP(strings.TrimSpace(start)) != nil in config-loading code before calling addRange.","If a hostname is intended, resolve it with net.LookupHost first and use the returned IP."],"exampleFix":"// before\nm.AddRange(\"192.168.1.256-192.168.1.260\") // parser_invalid_start_ip\n\n// after\nstart := net.ParseIP(\"192.168.1.250\")\nif start == nil { return fmt.Errorf(\"bad start IP\") }\nm.AddRange(\"192.168.1.250-192.168.1.260\")","handlingStrategy":"validation","validationCode":"func validStartIP(rng string) bool {\n    parts := strings.SplitN(rng, \"-\", 2)\n    if len(parts) != 2 {\n        return false\n    }\n    return net.ParseIP(strings.TrimSpace(parts[0])) != nil\n}","typeGuard":null,"tryCatchPattern":"if err := matcher.AddRange(rng); err != nil {\n    return fmt.Errorf(\"range %q rejected: %w\", rng, err)\n}","preventionTips":["Resolve hostnames to IPs before constructing ranges.","Strip non-ASCII whitespace from config values before parsing.","Lint range strings in CI with net.ParseIP."],"tags":["ip-range","parser","go","invalid-ip"],"backgroundTag":"invalid-argument-format","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}