jdx/mise · critical
refusing firewall default incoming {} over SSH: blocking rul
Error message
refusing firewall default incoming {} over SSH: blocking rule '{}' also covers peer {} on server port {}, and firewalld cannot guarantee the allow wins; narrow the rule or set allow_lockout = true What it means
The firewalld variant of the lockout guard: firewalld policies give no strict first-match ordering mise can rely on, so a blocking rule that also covers the current SSH peer and server port is refused regardless of declaration order — an allow elsewhere cannot be proven to win. The fix is to make the blocking rule stop matching the session, or to acknowledge the risk explicitly.
Source
Thrown at src/system/firewall.rs:509
.port
.is_none_or(|port| port.contains(connection.server_port))
&& rule
.source
.is_none_or(|source| source.contains(&connection.peer))
&& rule
.destination
.is_none_or(|destination| destination.contains(&connection.server))
}) {
if rule.action != FirewallAction::Allow {
match backend {
Some(FirewallBackend::Nftables | FirewallBackend::Ufw) if !covered => bail!(
"refusing firewall default incoming {} over SSH: blocking rule '{}' precedes a proven allow for peer {} on server port {}; reorder or narrow the rule, or set allow_lockout = true",
self.default_incoming.ufw(),
rule.name,
connection.peer,
connection.server_port
),
Some(FirewallBackend::Firewalld) => bail!(
"refusing firewall default incoming {} over SSH: blocking rule '{}' also covers peer {} on server port {}, and firewalld cannot guarantee the allow wins; narrow the rule or set allow_lockout = true",
self.default_incoming.ufw(),
rule.name,
connection.peer,
connection.server_port
),
// An automatic backend is validated again after it is
// resolved.
_ => {}
}
continue;
}
// SSH_CONNECTION does not identify the ingress interface. An
// interface-constrained allow cannot prove that it preserves this
// session, so keep looking for an unrestricted covering allow.
if rule.interface.is_none() {
covered = true;
if matches!(View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Narrow the blocking rule until it cannot match the session: different source CIDR excluding your peer, a port range excluding the SSH port, or a different interface scope.
- Pin `backend = "nftables"` or `"ufw"` (installing that tool if needed) where declaration order is honored, and put the allow first.
- With out-of-band console access, set `allow_lockout = true` under `[bootstrap.linux.firewall]` to accept the ambiguity.
Example fix
# before — firewalld cannot prove the allow wins backend = "firewalld" [[bootstrap.linux.firewall.rules]] name = "deny-guest" source = "0.0.0.0/0" port = "1-65535" protocol = "tcp" action = "deny" [[bootstrap.linux.firewall.rules]] name = "ssh-ops" source = "203.0.113.5/32" port = 22 protocol = "tcp" action = "allow" # after — exclude the management peer from the deny [[bootstrap.linux.firewall.rules]] name = "deny-guest" source = "0.0.0.0/1" # plus a second rule for 128.0.0.0/1, both excluding the peer port = "1-21" protocol = "tcp" action = "deny" # or simpler: pin backend = "nftables" and order the allow first
Defensive patterns
Strategy: try-catch
Validate before calling
# pre-flight: on firewalld, no deny rule may cover the SSH peer/port at all # (order cannot save you; narrow or exclude the peer before apply)
Try / catch
if ! mise bootstrap firewall apply 2>fw.err; then
if grep -q "firewalld cannot guarantee the allow wins" fw.err; then
echo "narrow the deny so it stops covering the SSH peer/port, or switch backend"; exit 1
fi
cat fw.err; exit 1
fi Prevention
- On firewalld hosts, never combine broad denies with a specific SSH allow — split or narrow them.
- Pin backend explicitly when porting configs across distros so ordering semantics match your rules.
- Keep management traffic on a dedicated port/CIDR that no deny rule touches.
When it happens
Trigger: Backend firewalld (pinned or auto-resolved), deny-ish `default_incoming`, and any non-allow rule whose source/port/destination match the `SSH_CONNECTION` peer and server port — even if an allow rule for the same session exists, firewalld cannot guarantee it takes precedence.
Common situations: RHEL/CentOS-family hosts where firewalld is the default; migrating iptables rule sets into policy objects; broad denies coexisting with a specific SSH allow on hosts that previously used nftables ordering semantics.
Related errors
- refusing firewall default incoming {} over SSH: blocking rul
- refusing firewall default incoming {} from an SSH-derived pr
- refusing firewall default incoming {} without SSH_CONNECTION
- refusing firewall default incoming {} over SSH: no incoming
- firewall rule '{}' uses interface matching, which firewalld
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/34b5e5ff07039f33.
Report an issue: GitHub.