shadow1ng/fscan · error

parser_start_gt_end

Error message

parser_start_gt_end

What it means

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.

Source

Thrown at common/parsers/host_iterator.go:379

		}
		parts := strings.Split(startIPStr, ".")
		if len(parts) != 4 {
			return nil, fmt.Errorf("%s", i18n.Tr("parser_invalid_ip_fmt", startIPStr))
		}
		parts[3] = strconv.Itoa(endNum)
		endIPStr = strings.Join(parts, ".")
	}

	start, ok := ipToUint32(startIP)
	if !ok {
		return nil, fmt.Errorf("%s", i18n.GetText("parser_ipv4_only"))
	}
	end, ok := ipToUint32(net.ParseIP(endIPStr))
	if !ok {
		return nil, fmt.Errorf("%s", i18n.Tr("parser_invalid_end_ip", endIPStr))
	}
	if start > end {
		return nil, fmt.Errorf("%s", i18n.GetText("parser_start_gt_end"))
	}
	return &cidrHostSource{current: start, end: end}, nil
}

func closeHostSources(sources []hostSource) {
	for _, src := range sources {
		_ = src.Close()
	}
}

type hostMatcher struct {
	exact  map[string]struct{}
	ranges []ipRange
}

type ipRange struct {
	start uint32
	end   uint32

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Swap the endpoints so start <= end: "192.168.0.10-192.168.0.254".
  2. Normalize in code: if ipToUint32(start) > ipToUint32(end), swap before calling addRange.
  3. Compute both endpoints from one source of truth (e.g. base+count) to avoid ordering mistakes.

Example fix

// before
m.AddRange("192.168.0.254-192.168.0.10") // parser_start_gt_end

// after
m.AddRange("192.168.0.10-192.168.0.254")
Defensive patterns

Strategy: validation

Validate before calling

func rangeOrdered(rng string) (bool, error) {
    parts := strings.SplitN(rng, "-", 2)
    if len(parts) != 2 {
        return false, fmt.Errorf("not a range")
    }
    s := net.ParseIP(strings.TrimSpace(parts[0])).To4()
    e := net.ParseIP(strings.TrimSpace(parts[1])).To4()
    if s == nil || e == nil {
        return false, fmt.Errorf("non-IPv4 endpoint")
    }
    return binary.BigEndian.Uint32(s) <= binary.BigEndian.Uint32(e), nil
}

Try / catch

if err := matcher.AddRange(rng); err != nil {
    if start, end, ok := normalizeRange(rng); ok {
        return matcher.AddRange(start + "-" + end) // swap and retry once
    }
    return err
}

Prevention

When it happens

Trigger: 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".

Common situations: Swapped copy-paste of the two endpoints; reverse-order ranges written assuming the tool normalizes direction; generating ranges from loop variables with inverted bounds.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/3779b71cd3e18101. Report an issue: GitHub.