{"record":{"id":"d27e72d4c468ee92","repo":"shadow1ng/fscan","slug":"parser-invalid-end-ip","errorCode":null,"errorMessage":"parser_invalid_end_ip","messagePattern":"parser_invalid_end_ip","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/parsers/host_iterator.go","lineNumber":376,"sourceCode":"\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\"))\n\t}\n\tend, ok := ipToUint32(net.ParseIP(endIPStr))\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_end_ip\", endIPStr))\n\t}\n\tif start > end {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.GetText(\"parser_start_gt_end\"))\n\t}\n\treturn &cidrHostSource{current: start, end: end}, nil\n}\n\nfunc closeHostSources(sources []hostSource) {\n\tfor _, src := range sources {\n\t\t_ = src.Close()\n\t}\n}\n\ntype hostMatcher struct {\n\texact  map[string]struct{}\n\tranges []ipRange\n}\n","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/common/parsers/host_iterator.go#L358-L394","documentation":"The end of an IP range could not be converted to a uint32 via ipToUint32(net.ParseIP(endIPStr)). In the full-IP end form, the end string must be a valid IPv4 literal; an IPv6 end address or an end that fails to parse fails this conversion and the message names the offending end string.","triggerScenarios":"addRange with an IPv6 end such as \"10.0.0.1-::1\" or a full end string that net.ParseIP rejects (e.g. \"10.0.0.1-10.0.0.\"), after the short-tail branch was skipped because the tail contained dots.","commonSituations":"Mixed-family ranges where one end was taken from an IPv6 interface address; truncated end IPs from hand-edited config files.","solutions":["Provide a complete, valid IPv4 end address: \"10.0.0.1-10.0.0.254\".","Validate both ends with net.ParseIP(e).To4() != nil before addRange.","For tails that contain dots, ensure all four octets are present and numeric."],"exampleFix":"// before\nm.AddRange(\"10.0.0.1-10.0.0.\") // parser_invalid_end_ip\n\n// after\nm.AddRange(\"10.0.0.1-10.0.0.254\")","handlingStrategy":"validation","validationCode":"func validEndIP(rng string) bool {\n    parts := strings.SplitN(rng, \"-\", 2)\n    if len(parts) != 2 {\n        return false\n    }\n    tail := strings.TrimSpace(parts[1])\n    if strings.Contains(tail, \".\") {\n        ip := net.ParseIP(tail)\n        return ip != nil && ip.To4() != nil\n    }\n    return true\n}","typeGuard":"func isIPv4(ip net.IP) bool { return ip != nil && ip.To4() != nil }","tryCatchPattern":"if err := matcher.AddRange(rng); err != nil {\n    return fmt.Errorf(\"fix end of %q: %w\", rng, err)\n}","preventionTips":["Never truncate end IPs when editing config files by hand.","Validate both endpoints with net.ParseIP before submission."],"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"}