shadow1ng/fscan · error
parser_invalid_ip_fmt
Error message
parser_invalid_ip_fmt
What it means
When the short-tail branch rewrites the start IP's last octet, it requires the start string to contain exactly four dot-separated octets. If strings.Split(startIPStr, ".") yields anything other than 4 parts, this formatted message naming the start string is returned. Note startIP already parsed as an IP, so this mainly guards odd canonical forms before octet substitution.
Source
Thrown at common/parsers/host_iterator.go:364
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"))
}
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
}View on GitHub (pinned to 95cc12e753)
Solutions
- Pass the start IP in standard dotted-quad form, e.g. "192.168.1.1-50".
- Normalize the string first: verify strings.Count(start, ".") == 3 before addRange.
- Avoid abbreviated IPv4 forms (e.g. "127.1") which net.ParseIP may accept but lack four dotted parts.
Example fix
// before
m.AddRange("192.168.1-50") // ambiguous; may hit parser_invalid_ip_fmt
// after
m.AddRange("192.168.0.1-50") // full dotted-quad start plus numeric tail Defensive patterns
Strategy: validation
Validate before calling
func startIsDottedQuad(rng string) bool {
parts := strings.SplitN(rng, "-", 2)
if len(parts) != 2 {
return false
}
return len(strings.Split(strings.TrimSpace(parts[0]), ".")) == 4
} Try / catch
if err := matcher.AddRange(rng); err != nil {
return fmt.Errorf("normalize %q to dotted-quad: %w", rng, err)
} Prevention
- Always emit canonical dotted-quad IPv4 strings (net.IP.String() of a To4 address).
- Reject abbreviated IP forms in input validation.
When it happens
Trigger: addRange with a start IP that parses but does not have 4 dot-separated labels in its original string form combined with a numeric short tail, e.g. unusual formatting of the start portion in "ip-tail" notation.
Common situations: Programmatically generated range strings using abbreviated IP forms; localization/formatting layers that mangle dotted-quad strings before they reach addRange.
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_range_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/a30b57b94ebc3735.
Report an issue: GitHub.