shadow1ng/fscan · error

parser_invalid_end_ip

Error message

parser_invalid_end_ip

What it means

The end of an IP range could not be converted to a uint32 via ipToUint32(net.ParseIP(endIPStr)). In the full-IP end form, the end string must be a valid IPv4 literal; an IPv6 end address or an end that fails to parse fails this conversion and the message names the offending end string.

Source

Thrown at common/parsers/host_iterator.go:376

		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
}

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

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

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Provide a complete, valid IPv4 end address: "10.0.0.1-10.0.0.254".
  2. Validate both ends with net.ParseIP(e).To4() != nil before addRange.
  3. For tails that contain dots, ensure all four octets are present and numeric.

Example fix

// before
m.AddRange("10.0.0.1-10.0.0.") // parser_invalid_end_ip

// after
m.AddRange("10.0.0.1-10.0.0.254")
Defensive patterns

Strategy: validation

Validate before calling

func validEndIP(rng string) bool {
    parts := strings.SplitN(rng, "-", 2)
    if len(parts) != 2 {
        return false
    }
    tail := strings.TrimSpace(parts[1])
    if strings.Contains(tail, ".") {
        ip := net.ParseIP(tail)
        return ip != nil && ip.To4() != nil
    }
    return true
}

Type guard

func isIPv4(ip net.IP) bool { return ip != nil && ip.To4() != nil }

Try / catch

if err := matcher.AddRange(rng); err != nil {
    return fmt.Errorf("fix end of %q: %w", rng, err)
}

Prevention

When it happens

Trigger: addRange with an IPv6 end such as "10.0.0.1-::1" or a full end string that net.ParseIP rejects (e.g. "10.0.0.1-10.0.0."), after the short-tail branch was skipped because the tail contained dots.

Common situations: Mixed-family ranges where one end was taken from an IPv6 interface address; truncated end IPs from hand-edited config files.

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/d27e72d4c468ee92. Report an issue: GitHub.