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

  1. Supply exactly one dash separating a start and end: "192.168.1.1-192.168.1.50".
  2. Use the short-tail form "192.168.1.1-50" for same-/24 ranges, or CIDR "192.168.1.0/24" for whole networks.
  3. 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

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


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