jdx/mise · critical
refusing firewall default incoming {} without SSH_CONNECTION
Error message
refusing firewall default incoming {} without SSH_CONNECTION because process ancestry could not be inspected; set allow_lockout = true to acknowledge the lockout risk What it means
The same lockout guard with an even weaker position: `SSH_CONNECTION` is absent and process-ancestry inspection returned no verdict (None), so mise cannot even tell whether the current process derives from SSH. Because an uninspectable session might be the one about to be cut off by a deny-by-default incoming policy, it fails closed and demands an explicit `allow_lockout = true` acknowledgment.
Source
Thrown at src/system/firewall.rs:477
&self,
rules: &[FirewallRule],
backend: Option<FirewallBackend>,
ssh_ancestor: Option<bool>,
) -> Result<()> {
if self.state != FirewallState::Enabled
|| self.default_incoming == FirewallPolicy::Allow
|| self.allow_lockout
{
return Ok(());
}
let Some(connection) = &self.ssh_connection else {
return match ssh_ancestor {
Some(false) => Ok(()),
Some(true) => bail!(
"refusing firewall default incoming {} from an SSH-derived process without SSH_CONNECTION: mise cannot verify that remote access will survive; preserve SSH_CONNECTION or set allow_lockout = true",
self.default_incoming.ufw()
),
None => bail!(
"refusing firewall default incoming {} without SSH_CONNECTION because process ancestry could not be inspected; set allow_lockout = true to acknowledge the lockout risk",
self.default_incoming.ufw()
),
};
};
let mut covered = false;
for rule in rules.iter().filter(|rule| {
rule.state == FirewallRuleState::Present
&& rule.direction == FirewallDirection::Incoming
&& rule
.protocol
.is_none_or(|protocol| protocol == FirewallProtocol::Tcp)
&& rule
.port
.is_none_or(|port| port.contains(connection.server_port))
&& rule
.source
.is_none_or(|source| source.contains(&connection.peer))View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Set `allow_lockout = true` in `[bootstrap.linux.firewall]` only once you can prove access survives (out-of-band console, or a pre-existing allow rule for your IP/port).
- Run from a normal interactive SSH login shell with SSH_CONNECTION preserved so the guard verifies rule coverage instead of failing closed.
- Relax the sandbox/hidepid restriction for this invocation so ancestry inspection works.
- Pre-add an unrestricted-interface TCP allow for your management peer and port, then re-run.
Example fix
# before mise bootstrap firewall apply # error: refusing firewall default incoming deny without SSH_CONNECTION because # process ancestry could not be inspected ... # after — from the direct SSH shell, with the variable intact ssh host mise bootstrap firewall apply # or, with console access available, acknowledge the risk: # [bootstrap.linux.firewall] # allow_lockout = true
Defensive patterns
Strategy: try-catch
Validate before calling
# pre-flight in restricted environments: prove reachability or stop
[ -n "$SSH_CONNECTION" ] || { echo 'ancestry may be uninspectable here; run from the login shell or set allow_lockout'; exit 1; } Try / catch
if ! mise bootstrap firewall apply 2>fw.err; then
if grep -q "process ancestry could not be inspected" fw.err; then
echo "sandboxed run; re-run from the SSH login shell or acknowledge via allow_lockout"; exit 1
fi
cat fw.err; exit 1
fi Prevention
- Avoid running firewall convergence from containers/sandboxes with hidden /proc.
- Keep the SSH login shell as the launch point for destructive host changes.
- Pre-create an unrestricted-interface allow for the management peer/port so the guard can pass on rule coverage.
When it happens
Trigger: `mise bootstrap firewall apply` with deny-ish `default_incoming`, no `SSH_CONNECTION` in the environment, and the ssh_ancestor probe indeterminate — hardened /proc permissions (hidepid), containers/sandboxes hiding the parent chain, or unusual process trees that defeat inspection.
Common situations: Running inside containers, chroots, or restricted unprivileged environments where /proc ancestry is hidden; CI runners with strict sandboxing; environments where both environment variables and /proc are locked down for hygiene.
Related errors
- refusing firewall default incoming {} from an SSH-derived pr
- refusing firewall default incoming {} over SSH: blocking rul
- refusing firewall default incoming {} over SSH: blocking rul
- refusing firewall default incoming {} over SSH: no incoming
- SSH_CONNECTION must contain client address/port and server a
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/f1e6fc9c8704006e.
Report an issue: GitHub.