XIU2/CloudflareSpeedTest · error

ParseCIDR err

Error message

ParseCIDR err

What it means

task/ip.go:69-74 wraps net.ParseCIDR in log.Fatalln, so any IP/CIDR that Go cannot parse terminates the whole process with 'ParseCIDR err'. fixIP() first appends /32 or /128 to bare addresses, so this fires only for genuinely malformed input (bad octets, invalid mask, non-IP text). It is called once per line of ip.txt / -f and once per comma element of -ip, from loadIPRanges().

Source

Thrown at task/ip.go:72

	// 如果不含有 '/' 则代表不是 IP 段,而是一个单独的 IP,因此需要加上 /32 /128 子网掩码
	if i := strings.IndexByte(ip, '/'); i < 0 {
		if isIPv4(ip) {
			r.mask = "/32"
		} else {
			r.mask = "/128"
		}
		ip += r.mask
	} else {
		r.mask = ip[i:]
	}
	return ip
}

// 解析 IP 段,获得 IP、IP 范围、子网掩码
func (r *IPRanges) parseCIDR(ip string) {
	var err error
	if r.firstIP, r.ipNet, err = net.ParseCIDR(r.fixIP(ip)); err != nil {
		log.Fatalln("ParseCIDR err", err)
	}
}

func (r *IPRanges) appendIPv4(d byte) {
	r.appendIP(net.IPv4(r.firstIP[12], r.firstIP[13], r.firstIP[14], d))
}

func (r *IPRanges) appendIP(ip net.IP) {
	r.ips = append(r.ips, &net.IPAddr{IP: ip})
}

// 返回第四段 ip 的最小值及可用数目
func (r *IPRanges) getIPRange() (minIP, hosts byte) {
	minIP = r.firstIP[15] & r.ipNet.Mask[3] // IP 第四段最小值

	// 根据子网掩码获取主机数量
	m := net.IPv4Mask(255, 255, 255, 255)
	for i, v := range r.ipNet.Mask {

View on GitHub (pinned to 1da0c025d7)

Solutions

  1. Open the file/argument named in the log output and fix or delete the offending line (the error text includes net.ParseCIDR's reason, e.g. 'invalid CIDR address').
  2. Remove comment lines and trailing whitespace/CR characters from ip.txt; only one CIDR per line is supported.
  3. If you inject IP data from another tool, validate each entry with net.ParseCIDR (or `prips`/`python ipaddress`) before writing it.
  4. As a code-level hardening, downgrade log.Fatalln to a warning that skips the bad entry so one typo cannot kill a long run.

Example fix

// before (task/ip.go:71)
if r.firstIP, r.ipNet, err = net.ParseCIDR(r.fixIP(ip)); err != nil {
    log.Fatalln("ParseCIDR err", err)
}
// after
if r.firstIP, r.ipNet, err = net.ParseCIDR(r.fixIP(ip)); err != nil {
    utils.Yellow.Printf("[跳过] 无效 IP 段 [%s]: %v\n", ip, err)
    r.firstIP, r.ipNet = nil, nil
    return
}
// callers must then skip entries where r.ipNet == nil
Defensive patterns

Strategy: type-guard

Validate before calling

# shell: validate the IP file before running
while IFS= read -r line; do
  case "$line" in ''|'#'*) continue;; esac
  ipcalc -c "$line" >/dev/null 2>&1 || { echo "bad CIDR: $line"; exit 1; }
done < ip.txt

Type guard

// isCIDR reports whether s is a bare IP or a valid CIDR,
// mirroring fixIP()'s /32,/128 append before net.ParseCIDR.
func isCIDR(s string) bool {
	if !strings.Contains(s, "/") {
		s += "/32"
	}
	_, _, err := net.ParseCIDR(s)
	return err == nil
}

Prevention

When it happens

Trigger: A line in the IP file such as '1.2.3.256/24', '10.0.0.0/33', 'not-an-ip', or a comment line; or a malformed element in -ip 1.1.1.1,foo/24. Empty lines are skipped, but any other non-CIDR text is fatal. Note fixIP's isIPv4 check failing makes it append /128, which then fails ParseCIDR for garbage strings.

Common situations: Editing ip.txt and leaving a comment like '# Cloudflare'; a Windows editor saving with stray characters; pasting a URL instead of a CIDR; mixing in an IP with a hostname; using a /33+ mask or an octet > 255.

Related errors


AI-assisted analysis of XIU2/CloudflareSpeedTest@1da0c025d7 (2026-08-15). Data as JSON: /api/errors/b6d7b5747a73116f. Report an issue: GitHub.