jdx/mise · error

firewall port range {start}-{end} is invalid

Error message

firewall port range {start}-{end} is invalid

What it means

Validates the parsed port range of a firewall rule: after splitting the string, both endpoints must be non-zero u16 values and start must not exceed end (`start == 0 || end == 0 || start > end` aborts). Firewall ports are 1-65535 and the range is inclusive. Ports above 65535 fail earlier as a u16 parse error, so this message specifically covers zero or reversed bounds.

Source

Thrown at src/system/firewall.rs:196

#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct FirewallPort {
    start: u16,
    end: u16,
}

impl FirewallPort {
    fn from_toml(value: FirewallPortToml) -> Result<Self> {
        let (start, end) = match value {
            FirewallPortToml::Single(port) => (port, port),
            FirewallPortToml::Range(range) => {
                let Some((start, end)) = range.split_once(['-', ':']) else {
                    bail!("firewall port '{range}' must be a number or inclusive range")
                };
                (start.parse()?, end.parse()?)
            }
        };
        if start == 0 || end == 0 || start > end {
            bail!("firewall port range {start}-{end} is invalid");
        }
        Ok(Self { start, end })
    }

    fn contains(self, port: u16) -> bool {
        self.start <= port && port <= self.end
    }

    fn render(self, separator: char) -> String {
        if self.start == self.end {
            self.start.to_string()
        } else {
            format!("{}{separator}{}", self.start, self.end)
        }
    }
}

#[derive(Clone, Debug, Deserialize)]

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Order the range ascending: `port = "8000-9000"`.
  2. Never use port 0 — to match all ports, omit the `port` key entirely (then `protocol` is also optional).
  3. Re-check typos where bounds and separator got mangled ("80-.443", "80:-443").
  4. Run `mise bootstrap firewall status` after editing to surface config errors without touching the firewall.

Example fix

# before
[[bootstrap.linux.firewall.rules]]
name = "high-ports"
port = "9000-8000"
protocol = "udp"

# after
[[bootstrap.linux.firewall.rules]]
name = "high-ports"
port = "8000-9000"
protocol = "udp"
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight: ranges ascending, no zero endpoints
python3 - <<'PY'
import tomllib
fw = tomllib.load(open('mise.toml','rb')).get('bootstrap',{}).get('linux',{}).get('firewall',{})
for r in fw.get('rules',[]):
    p = r.get('port')
    if isinstance(p, str) and '-' in p or isinstance(p, str) and ':' in p:
        a, b = p.replace(':', '-').split('-', 1)
        if not (1 <= int(a) <= int(b) <= 65535):
            raise SystemExit(f"rule {r['name']}: invalid port range {p}")
PY

Prevention

When it happens

Trigger: `port = "0-65535"` or `port = 0` (zero is not a valid port), or a reversed range such as `port = "9000-8000"` where start > end after parsing.

Common situations: Writing ranges backwards assuming they are normalized; using 0 as a wildcard meaning "any port" (not supported — omit `port` instead); inverted ranges copied from another tool's output.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/67c15c9bbc0cb267. Report an issue: GitHub.