jdx/mise · error
firewall rule '{}' uses protocol {}, which UFW does not supp
Error message
firewall rule '{}' uses protocol {}, which UFW does not support; select backend = \"nftables\" or \"firewalld\" What it means
UFW has no support for the SCTP or DCCP protocols, so `validate_backend_request` rejects a rule whose `protocol` is "sctp" or "dccp" when the effective backend is ufw, before any planning. nftables and firewalld support both protocols; alternatively drop the SCTP/DCCP-specific rule from a ufw-managed config.
Source
Thrown at src/system/firewall.rs:1044
FirewallBackend::Auto => false,
}
}
fn validate_backend_request(request: &FirewallRequest, backend: FirewallBackend) -> Result<()> {
for rule in &request.rules {
if backend == FirewallBackend::Firewalld && rule.interface.is_some() {
bail!(
"firewall rule '{}' uses interface matching, which firewalld policies cannot express safely; select backend = \"nftables\" or \"ufw\"",
rule.name
);
}
if backend == FirewallBackend::Ufw
&& matches!(
rule.protocol,
Some(FirewallProtocol::Sctp | FirewallProtocol::Dccp)
)
{
bail!(
"firewall rule '{}' uses protocol {}, which UFW does not support; select backend = \"nftables\" or \"firewalld\"",
rule.name,
rule.protocol.expect("matched protocol").as_str()
);
}
}
Ok(())
}
fn validate_effective_backend_request(
request: &FirewallRequest,
effective: &FirewallRequest,
backend: FirewallBackend,
) -> Result<()> {
if effective.state == FirewallState::Enabled {
validate_backend_request(effective, backend)?;
request.validate_safety_with_rules(
&effective.rules,View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Pin `backend = "nftables"` or `backend = "firewalld"` in `[bootstrap.linux.firewall]` (installing it if needed).
- Drop the sctp/dccp rule if those protocols do not actually traverse this host (and drop its `port` too, since port requires protocol).
- Keep the ufw config tcp/udp-only and manage SCTP/DCCP rules out-of-band with nft.
Example fix
# before (mise.toml) [bootstrap.linux.firewall] backend = "ufw" [[bootstrap.linux.firewall.rules]] name = "sctp-media" port = 5000 protocol = "sctp" action = "allow" # after [bootstrap.linux.firewall] backend = "nftables" [[bootstrap.linux.firewall.rules]] name = "sctp-media" port = 5000 protocol = "sctp" action = "allow"
Defensive patterns
Strategy: validation
Validate before calling
# pre-flight: ufw supports only tcp/udp protocols
python3 - <<'PY'
import tomllib
fw = tomllib.load(open('mise.toml','rb')).get('bootstrap',{}).get('linux',{}).get('firewall',{})
if fw.get('backend') == 'ufw':
for r in fw.get('rules',[]):
if r.get('protocol') in ('sctp', 'dccp'):
raise SystemExit(f"rule {r['name']}: ufw does not support {r['protocol']}")
PY Prevention
- Need SCTP/DCCP? Pin backend = "nftables" or "firewalld" from the start.
- Keep ufw-backed configs tcp/udp-only.
- When copying rules from nftables, re-check each protocol against the target backend.
When it happens
Trigger: `backend = "ufw"` (pinned or auto-detected) plus a rule with `protocol = "sctp"` or `protocol = "dccp"` — typically needed for WebRTC/media stacks, SS7/SIGTRAN, or DCCP-based services.
Common situations: Copying an nftables ruleset into mise config on an Ubuntu host where ufw won; telecom/signaling workloads needing SCTP on a ufw-managed box; config shared across machines with different backends.
Related errors
- firewall backend '{}' requires command '{}'
- firewall rule '{}' uses interface matching, which firewalld
- firewall port '{range}' must be a number or inclusive range
- firewall port range {start}-{end} is invalid
- firewall rule '{}' is declared more than once
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/def3a75ec199590d.
Report an issue: GitHub.