shadowsocks/shadowsocks-rust · critical
open /dev/pf {err}
Error message
open /dev/pf {err} What it means
Same lazy /dev/pf initialization as the permission-denied variant, but for any other I/O error while opening the packet filter device. The message embeds the underlying `err` (e.g. ENOENT when /dev/pf does not exist). The program panics because the BSD redir cannot function without pf.
Source
Thrown at crates/shadowsocks-service/src/local/redir/sys/unix/bsd_pf.rs:376
)))
}
}
impl Drop for PacketFilter {
fn drop(&mut self) {
unsafe {
libc::close(self.fd);
}
}
}
pub static PF: LazyLock<PacketFilter> = LazyLock::new(|| match PacketFilter::open() {
Ok(pf) => pf,
Err(err) if err.kind() == ErrorKind::PermissionDenied => {
panic!("open /dev/pf permission denied, consider restart with root user");
}
Err(err) => {
panic!("open /dev/pf {err}");
}
});
View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Load the pf kernel module / enable pf so /dev/pf exists (`pfctl -e`, `kldload pf`)
- Run on the host or configure the jail/container to expose /dev/pf
- Verify the device node exists: ls -l /dev/pf, recreate via MAKEDEV if needed
- Inspect the embedded io::Error message for the exact underlying cause
Defensive patterns
Strategy: validation
Validate before calling
# verify /dev/pf exists and is openable before start: test -e /dev/pf || (kldload pf; pfctl -e)
Prevention
- Assert pf availability in the service's ExecStartPre
- Avoid running pf-dependent binaries inside jails/containers without /dev/pf
- Keep kernel pf module loaded at boot (/boot/loader.conf: pf_load="YES")
- Log the full io::Error from startup for diagnosis
When it happens
Trigger: First access of `static PF` in bsd_pf.rs triggers `PacketFilter::open()` and it fails with a non-PermissionDenied io::Error, producing `panic!("open /dev/pf {err}")`.
Common situations: pf kernel module not loaded (/dev/pf missing, ENOENT); running inside a container/jail without pf device; kernel built without pf support; device node permissions/ownership broken.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- open /dev/pf permission denied, consider restart with root u
- all plugins are exited. all connections may fail, check your
- {method} don't know how to generate nonce
- cannot get current working directory, {err:?}
- cannot get absolute path to working directory, {err:?}
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/9f93b52ef2d339b7.
Report an issue: GitHub.