{"record":{"id":"3779b71cd3e18101","repo":"shadow1ng/fscan","slug":"parser-start-gt-end","errorCode":null,"errorMessage":"parser_start_gt_end","messagePattern":"parser_start_gt_end","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/parsers/host_iterator.go","lineNumber":379,"sourceCode":"\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\ntype ipRange struct {\n\tstart uint32\n\tend   uint32","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/common/parsers/host_iterator.go#L361-L397","documentation":"The range is syntactically valid but its start address is numerically greater than its end address. newRangeHostSource compares the two uint32 values and refuses to build an empty/backwards host source, returning this message. Unlike the other range errors this is a semantic validation failure, not a parse failure.","triggerScenarios":"addRange with \"192.168.0.254-192.168.0.10\" or any start>end pair, including octet-swapped short tails like \"192.168.0.200-50\".","commonSituations":"Swapped copy-paste of the two endpoints; reverse-order ranges written assuming the tool normalizes direction; generating ranges from loop variables with inverted bounds.","solutions":["Swap the endpoints so start <= end: \"192.168.0.10-192.168.0.254\".","Normalize in code: if ipToUint32(start) > ipToUint32(end), swap before calling addRange.","Compute both endpoints from one source of truth (e.g. base+count) to avoid ordering mistakes."],"exampleFix":"// before\nm.AddRange(\"192.168.0.254-192.168.0.10\") // parser_start_gt_end\n\n// after\nm.AddRange(\"192.168.0.10-192.168.0.254\")","handlingStrategy":"validation","validationCode":"func rangeOrdered(rng string) (bool, error) {\n    parts := strings.SplitN(rng, \"-\", 2)\n    if len(parts) != 2 {\n        return false, fmt.Errorf(\"not a range\")\n    }\n    s := net.ParseIP(strings.TrimSpace(parts[0])).To4()\n    e := net.ParseIP(strings.TrimSpace(parts[1])).To4()\n    if s == nil || e == nil {\n        return false, fmt.Errorf(\"non-IPv4 endpoint\")\n    }\n    return binary.BigEndian.Uint32(s) <= binary.BigEndian.Uint32(e), nil\n}","typeGuard":null,"tryCatchPattern":"if err := matcher.AddRange(rng); err != nil {\n    if start, end, ok := normalizeRange(rng); ok {\n        return matcher.AddRange(start + \"-\" + end) // swap and retry once\n    }\n    return err\n}","preventionTips":["Normalize endpoint order at input time instead of trusting user ordering.","Derive ranges programmatically (base IP + host count) to avoid manual ordering mistakes."],"tags":["ip-range","parser","go","validation"],"backgroundTag":"invalid-argument-value","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"}