XX-net/XX-Net · warning
parse reserve port fail, line:%s, e:%r
Error message
parse reserve port fail, line:%s, e:%r
What it means
While scanning the Windows excluded port ranges (output of 'netsh int ipv4 show excludedportrange protocol=tcp'), the launcher could not parse a line into two integers (start/end of a range). This is a warning-level diagnostic: the unparseable line is skipped with 'continue' and scanning proceeds, so it never aborts the port-conflict check.
Source
Thrown at code/default/launcher/win_compat_suggest.py:97
x_tunnel_config_fn = os.path.join(data_path, "x_tunnel", "client.json")
x_tunnel_port = self.get_config_value(x_tunnel_config_fn, "socks_port", 1080)
return [web_console_port, smart_router_socks_port, smart_router_dns_port, x_tunnel_port]
def is_port_reserve_conflict(self):
cmd = "netsh int ipv4 show excludedportrange protocol=tcp"
lines = self.run_cmd(cmd)
for line in lines:
if not line.startswith(b" "):
continue
range_str = line.split()
try:
p0 = int(range_str[0])
p1 = int(range_str[1])
except Exception as e:
xlog.warn("parse reserve port fail, line:%s, e:%r", line, e)
continue
# xlog.debug("range:%d - %d", p0, p1)
for port in self.service_ports:
if p0 < port < p1:
xlog.info("found port reserved range:%d - %d, expect %d", p0, p1, port)
return True
return False
def search_port_range(self):
port_number = 16384
for port_start in range(10000, 45000, 5000):
port_end = port_start + port_number
acceptable = True
for port in self.service_ports:
if port_start <= port <= port_end:
acceptable = FalseView on GitHub (pinned to cfa5bc17b6)
Solutions
- Check the logged raw line to see whether it is just a header/blank line (harmless — ignore the warning).
- Run 'netsh int ipv4 show excludedportrange protocol=tcp' manually and compare its layout with the parser's expectations.
- If output is localized, force English output or make the parser skip lines that don't match a digits-only pattern before int().
- Update win_compat_suggest.py to filter lines with a regex like r'^\s*\d+\s+\d+' before parsing.
Example fix
// before
range_str = line.split()
try:
p0 = int(range_str[0])
p1 = int(range_str[1])
except Exception as e:
xlog.warn("parse reserve port fail, line:%s, e:%r", line, e)
continue
// after
import re
m = re.match(r'^\s*(\d+)\s+(\d+)', line)
if not m:
xlog.debug("skip non-range line:%r", line)
continue
p0, p1 = int(m.group(1)), int(m.group(2)) Defensive patterns
Strategy: validation
Validate before calling
import re
def is_port_range_line(line):
return bool(re.match(r'^\s*\d+\s+\d+\s*$', line))
# before parsing each netsh output line:
if not is_port_range_line(line):
continue Prevention
- Filter netsh output lines with a digits-pair regex before int() conversion.
- Strip headers and blank lines from command output before parsing.
- Never assume locale-fixed command output on Windows; match structure, not position.
When it happens
Trigger: Calling is_port_reserve_conflict() (directly or via check_and_resolve) on Windows when netsh output contains a header line, blank line, or localized/unexpected formatting, so line.split() yields fewer than 2 tokens or non-numeric tokens, making int(range_str[0])/int(range_str[1]) raise ValueError/IndexError.
Common situations: Non-English Windows where netsh prints localized headers; netsh output format differences across Windows 10/11 or Server editions; trailing blank lines in command output; systems where Hyper-V/WSL adds unusual range rows.
Related errors
AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27).
Data as JSON: /api/errors/8892b713576a948d.
Report an issue: GitHub.