shadow1ng/fscan · error
parser_invalid_ip_range_fmt
Error message
parser_invalid_ip_range_fmt
What it means
newRangeHostSource rejects an IP-range string that does not split into exactly two dash-separated parts. The range format is strictly "startIP-endIP" (or "startIP-lastOctet"); strings like "1.1.1.1-2-3", empty strings, or "1.1.1.1-" fail strings.Split on "-" with a length other than 2 and return this formatted message including the offending range string.
Source
Thrown at common/parsers/host_iterator.go:347
return nil, fmt.Errorf("%s", i18n.GetText("parser_ipv4_only"))
}
ones, bits := ipNet.Mask.Size()
if bits != 32 {
return nil, fmt.Errorf("%s", i18n.GetText("parser_ipv4_only"))
}
size := uint64(1) << uint(32-ones)
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))
}View on GitHub (pinned to 95cc12e753)
Solutions
- Supply exactly one dash separating a start and end: "192.168.1.1-192.168.1.50".
- Use the short-tail form "192.168.1.1-50" for same-/24 ranges, or CIDR "192.168.1.0/24" for whole networks.
- Pre-validate with strings.Count(rangeStr, "-") == 1 before calling addRange.
Example fix
// before
m.AddRange("10.0.0.1-10.0.0.254-x") // parser_invalid_ip_range_fmt
// after
if strings.Count(rng, "-") != 1 {
return fmt.Errorf("range must be start-end: %q", rng)
}
m.AddRange("10.0.0.1-10.0.0.254") Defensive patterns
Strategy: validation
Validate before calling
func isWellFormedRange(s string) bool {
return strings.Count(s, "-") == 1 &&
len(strings.TrimSpace(strings.SplitN(s, "-", 2)[0])) > 0 &&
len(strings.TrimSpace(strings.SplitN(s, "-", 2)[1])) > 0
} Try / catch
src, err := newRangeHostSource(rng)
if err != nil {
log.Printf("invalid range %q: %v", rng, err)
return nil
} Prevention
- Escape or reject hyphenated hostnames in range fields at the config schema level.
- Offer users distinct fields for CIDR vs range notation to avoid format confusion.
When it happens
Trigger: Calling addRange/newHostSource with strings containing more than one dash (e.g. "10.0.0.1-10.0.0-5"), no dash at all (e.g. "10.0.0.1"), or a trailing dash ("10.0.0.1-").
Common situations: Users writing hyphenated hostnames or FQDN ranges ("web-01-web-05") into an IP-range field; confusion between CIDR notation and range notation; typos with extra dashes copied from spreadsheets.
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_ip_fmt
- parser_invalid_start_ip
- parser_invalid_ip_end_val
- parser_invalid_end_ip
- parser_start_gt_end
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/f7baa5ba21d47641.
Report an issue: GitHub.