shadow1ng/fscan · error
parser_invalid_start_ip
Error message
parser_invalid_start_ip
What it means
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.
Source
Thrown at common/parsers/host_iterator.go:354
end := start + uint32(size-1)
if size > 2 {
start++
end--
}
return &cidrHostSource{current: start, end: end}, nil
}
func newRangeHostSource(rangeStr string) (hostSource, error) {
parts := strings.Split(rangeStr, "-")
if len(parts) != 2 {
return nil, fmt.Errorf("%s", i18n.Tr("parser_invalid_ip_range_fmt", rangeStr))
}
startIPStr := strings.TrimSpace(parts[0])
endIPStr := strings.TrimSpace(parts[1])
startIP := net.ParseIP(startIPStr)
if startIP == nil {
return nil, fmt.Errorf("%s", i18n.Tr("parser_invalid_start_ip", startIPStr))
}
if len(endIPStr) < 4 || !strings.Contains(endIPStr, ".") {
endNum, err := strconv.Atoi(endIPStr)
if err != nil || endNum > 255 {
return nil, fmt.Errorf("%s", i18n.Tr("parser_invalid_ip_end_val", endIPStr))
}
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"))View on GitHub (pinned to 95cc12e753)
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.
Example fix
// before
m.AddRange("192.168.1.256-192.168.1.260") // parser_invalid_start_ip
// after
start := net.ParseIP("192.168.1.250")
if start == nil { return fmt.Errorf("bad start IP") }
m.AddRange("192.168.1.250-192.168.1.260") Defensive patterns
Strategy: validation
Validate before calling
func validStartIP(rng string) bool {
parts := strings.SplitN(rng, "-", 2)
if len(parts) != 2 {
return false
}
return net.ParseIP(strings.TrimSpace(parts[0])) != nil
} Try / catch
if err := matcher.AddRange(rng); err != nil {
return fmt.Errorf("range %q rejected: %w", rng, err)
} Prevention
- Resolve hostnames to IPs before constructing ranges.
- Strip non-ASCII whitespace from config values before parsing.
- Lint range strings in CI with net.ParseIP.
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- parser_invalid_end_ip
- parser_invalid_ip_range_fmt
- parser_invalid_ip_end_val
- parser_invalid_ip_fmt
- parser_start_gt_end
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/ebeb661f4c4ede36.
Report an issue: GitHub.