jdx/mise · error

firewall interface ' ' is invalid

Error message

firewall interface '{interface}' is invalid

What it means

Interface names must be non-empty, at most 15 bytes (the Linux kernel IFNAMSIZ limit), and composed only of ASCII letters, digits, '-', '_', '.' or ':'. Validation bails with the offending value when any constraint fails. This mirrors kernel interface-name rules so generated backend commands reference real devices.

Solutions

  1. Use the exact kernel device name as shown by `ip link` (e.g. eth0, ens5, br0), within 15 bytes.
  2. Trim whitespace and strip invalid characters from configuration inputs before validation.
  3. Shorten interface/bridge names at creation time so they fit within 15 characters.
  4. Pre-validate interface strings with a regex like ^[A-Za-z0-9._:-]{1,15}$ when loading config.

Example fix

// before
let interface = "my-long-bridge-interface-name"; // 27 chars > 15
// after
let interface = "br-lan";
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_interface(interface: &str) -> bool {
    !interface.is_empty()
        && interface.len() <= 15
        && interface.bytes().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'-' | b'_' | b'.' | b':'))
}

Prevention

When it happens

Trigger: Passing an interface string that is empty, longer than 15 characters, or contains characters outside [A-Za-z0-9._:-] (e.g. "eth0 ", "br lan", unicode) to interface validation in a firewall rule.

Common situations: Typing a descriptive name instead of the device name ("wan interface"); 16+ character VLAN or bridge names exceeding IFNAMSIZ; trailing whitespace from YAML/ENV values; path-like names copied from elsewhere containing '/'.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/f007a20f57df3869. Report an issue: GitHub.

Appendix: source

Thrown at src/system/firewall.rs:2045

    if name.is_empty()
        || name.len() > 64
        || !name
            .bytes()
            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_'))
    {
        bail!("firewall rule name '{name}' must contain only ASCII letters, numbers, '-' or '_'");
    }
    Ok(())
}

fn validate_interface(interface: &str) -> Result<String> {
    if interface.is_empty()
        || interface.len() > 15
        || !interface
            .bytes()
            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_' | b'.' | b':'))
    {
        bail!("firewall interface '{interface}' is invalid");
    }
    Ok(interface.to_string())
}

fn parse_ssh_connection(value: &str) -> Result<SshConnection> {
    let fields = value.split_ascii_whitespace().collect::<Vec<_>>();
    if fields.len() != 4 {
        bail!("SSH_CONNECTION must contain client address/port and server address/port");
    }
    Ok(SshConnection {
        peer: fields[0].parse()?,
        server: fields[2].parse()?,
        server_port: fields[3].parse()?,
    })
}

/// Detect an sshd ancestor when SSH_CONNECTION was stripped by sudo, env -i,
/// or a wrapper. `None` fails closed because ancestry could not be inspected.

View on GitHub (pinned to 533346cc37)