jdx/mise · error
firewall backend ' ' requires command
Error message
firewall backend '{}' requires command '{}' What it means
This error fires when the selected firewall backend's underlying CLI program (nft, ufw, or firewall-cmd) is not found on the system. The library checks for the executable before attempting any firewall mutation and fails fast with the backend label and expected command name so the developer knows what to install. It is a preflight dependency check, not a command execution failure.
Solutions
- Install the CLI the backend requires (nft for nftables, ufw for ufw, firewall-cmd for firewalld).
- Select a backend whose command is already installed in the request's backend field.
- Verify PATH inside the execution context (systemd unit, container, cron) includes the directory containing the command.
- Check backend_available / run `which nft` etc. before invoking the API to fail early in your own code.
Example fix
// before
let request = FirewallRequest { backend: FirewallBackend::Firewalld, .. };
apply(&request, false, true)?; // fails: firewalld requires command 'firewall-cmd'
// after
// install firewalld (or switch backend)
let request = FirewallRequest { backend: FirewallBackend::Nftables, .. };
apply(&request, false, true)?; Defensive patterns
Strategy: validation
Validate before calling
fn backend_ready(backend: FirewallBackend) -> bool {
match backend.program() {
Some(program) => std::process::Command::new(program).arg("--version").output().is_ok(),
None => false,
}
} Try / catch
match ensure_backend_available(backend) {
Err(e) => eprintln!("install the backend CLI first: {e}"),
Ok(()) => apply(&request, false, true)?,
} Prevention
- Check backend_available before constructing requests
- Pin backend selection to what the host image ships
- Assert PATH contents in service/container contexts
- Document required packages per backend in deployment docs
When it happens
Trigger: Calling firewall apply/ensure_backend_available with a FirewallBackend whose program (per backend.program()) is absent from PATH, e.g. backend ufw on a host without the ufw binary installed.
Common situations: Running bootstrap on a minimal container or cloud image that ships no firewall CLI; selecting backend = "firewalld" on a Debian host where only ufw is installed; PATH is stripped in a systemd unit or cron context so the binary is not found.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- no supported firewall backend found (tried nft…
- a branch name is required
- a glob is required
- a repository preview directory requires a dry run
- a repository url is required
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/a4a26e96a32d8581.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/firewall.rs:993
}
}
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 533346cc37)