jdx/mise · error
firewall backend '{}' requires command '{}'
Error message
firewall backend '{}' requires command '{}' What it means
The config pins a specific firewall backend via `backend = "nftables" | "firewalld" | "ufw"`, but `ensure_backend_available` found that backend's CLI program is not on PATH, so mise refuses rather than silently switching backends. The message names both the selected backend label and the exact missing command. Install it, or drop/changed the `backend` key to let auto-detection pick what exists.
Source
Thrown at src/system/firewall.rs:983
}
}
for backend in [
FirewallBackend::Nftables,
FirewallBackend::Firewalld,
FirewallBackend::Ufw,
] {
if backend_available(backend) {
return Ok(backend);
}
}
bail!("no supported firewall backend found (tried nft, firewall-cmd, and ufw)")
}
fn ensure_backend_available(backend: FirewallBackend) -> Result<()> {
if backend_available(backend) {
Ok(())
} else {
bail!(
"firewall backend '{}' requires command '{}'",
backend.label(),
backend.program().unwrap_or_default()
)
}
}
fn backend_available(backend: FirewallBackend) -> bool {
backend.program().and_then(crate::file::which).is_some()
}
fn backend_active(backend: FirewallBackend) -> bool {
match backend {
FirewallBackend::Nftables => command_output("nft", &["list", "table", "inet", NFT_TABLE])
.is_ok_and(|output| output.status.success()),
FirewallBackend::Firewalld => {
command_output("firewall-cmd", &["--state"]).is_ok_and(|output| output.status.success())
}View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Install the named command: `apt install ufw`, `dnf install nftables`, `apt install nftables`, etc.
- Or drop `backend` from `[bootstrap.linux.firewall]` so auto-detection (nft, then firewall-cmd, then ufw) picks an installed one.
- Or change `backend` to the tool this host actually ships.
- Ensure the program is on PATH for the invoking context: `sudo env PATH="$PATH:/usr/sbin:/sbin" mise ...`.
Example fix
# before (mise.toml) [bootstrap.linux.firewall] backend = "ufw" # ufw not installed on this host # after — let mise pick what exists [bootstrap.linux.firewall] # backend omitted; auto-detects nft -> firewall-cmd -> ufw # or pin what is installed: backend = "nftables"
Defensive patterns
Strategy: fallback
Validate before calling
# pre-flight: the pinned backend's program must be on PATH case "$BACKEND" in nftables) command -v nft >/dev/null || echo 'install nftables' ;; firewalld) command -v firewall-cmd >/dev/null || echo 'install firewalld' ;; ufw) command -v ufw >/dev/null || echo 'install ufw' ;; esac
Prevention
- Pin `backend` only when the fleet is homogeneous; otherwise omit it for auto-detection.
- Verify with `mise bootstrap firewall status` after pinning.
- Install the backend package before the first bootstrap run.
When it happens
Trigger: `backend = "ufw"` on a firewalld-only RHEL box; `backend = "nftables"` where nft is not installed; or the command exists but is unreachable through the invoking PATH (sudo secure_path excluding /usr/sbin). Checked before any inspection or apply work.
Common situations: Sharing one mise.toml across heterogeneous hosts where only some have the pinned backend; minimal images; scripts that run mise under a reduced PATH; migrating configs from ufw machines to nftables-only servers.
Related errors
- no supported firewall backend found (tried nft, firewall-cmd
- firewall rule '{}' uses interface matching, which firewalld
- firewall rule '{}' uses protocol {}, which UFW does not supp
- firewall port '{range}' must be a number or inclusive range
- firewall port range {start}-{end} is invalid
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/a4a26e96a32d8581.
Report an issue: GitHub.