shadowsocks/shadowsocks-rust · error
not supported tcp transparent proxy type
Error message
not supported tcp transparent proxy type
What it means
On BSD platforms the TCP transparent-proxy bind function only supports RedirType::PacketFilter (freebsd/macos/ios) and RedirType::IpFirewall (freebsd/macos/ios). Passing any other RedirType (e.g. TProxy, Redirect) reaches the catch-all arm and throws InvalidInput.
Source
Thrown at crates/shadowsocks-service/src/local/redir/tcprelay/sys/unix/bsd.rs:29
use crate::{
config::RedirType,
local::redir::{
redir_ext::{TcpListenerRedirExt, TcpStreamRedirExt},
sys::set_ipv6_only,
},
};
impl TcpListenerRedirExt for TcpListener {
async fn bind_redir(ty: RedirType, addr: SocketAddr, accept_opts: AcceptOpts) -> io::Result<TcpListener> {
match ty {
#[cfg(any(target_os = "freebsd", target_os = "openbsd", target_os = "macos", target_os = "ios"))]
RedirType::PacketFilter => {}
#[cfg(any(target_os = "freebsd", target_os = "macos", target_os = "ios"))]
RedirType::IpFirewall => {}
_ => {
return Err(Error::new(
ErrorKind::InvalidInput,
"not supported tcp transparent proxy type",
));
}
}
// BSD platform doesn't have any special logic
let socket = match addr {
SocketAddr::V4(..) => TcpSocket::new_v4()?,
SocketAddr::V6(..) => TcpSocket::new_v6()?,
};
// On platforms with Berkeley-derived sockets, this allows to quickly
// rebind a socket, without needing to wait for the OS to clean up the
// previous one.
//
// On Windows, this allows rebinding sockets which are actively in use,
// which allows “socket hijacking”, so we explicitly don't set it here.View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Set local config `mode`/redir type to PacketFilter on macOS/iOS or PacketFilter/IpFirewall on FreeBSD.
- Run on Linux if you specifically need TProxy or Redirect mode.
- Check `shadowsocks-service --help` / server startup log for the list of supported redir types on your platform.
- Rebuild with platform-appropriate features if the binary was cross-compiled.
Example fix
// before (config on macOS)
{ "locals": [{ "type": "redir", "tcp_redir": "tproxy" }] }
// after
{ "locals": [{ "type": "redir", "tcp_redir": "packet-filter" }] } Defensive patterns
Strategy: validation
Validate before calling
// validate redir type for the platform before starting the local server #[cfg(any(target_os = "freebsd", target_os = "macos", target_os = "ios"))] assert!(matches!(ty, RedirType::PacketFilter | RedirType::IpFirewall));
Type guard
fn is_supported_tcp_redir(ty: &RedirType) -> bool {
matches!(ty, RedirType::PacketFilter | RedirType::IpFirewall) // BSD targets
} Try / catch
let listener = TcpListenerRedirExt::bind_redir(ty, addr, accept_opts).await.map_err(|e| {
anyhow::anyhow!("TCP redir type {:?} unsupported on this OS: {e}", ty)
})?; Prevention
- Use per-platform config files for the redir type
- Validate the redir type at config parse time against platform support
- Prefer the documented default (RedirType::tcp_default()) instead of hardcoding
When it happens
Trigger: Calling bind_redir with a RedirType not compiled in or not valid for the current BSD platform, e.g. requesting TProxy on macOS, or a config whose tcp redir type doesn't match the OS.
Common situations: Copying a Linux config (tproxy) to macOS/FreeBSD, or shadowsocks being built without the platform feature so the expected type falls into the unsupported arm.
Related errors
- not supported udp transparent proxy type
- not supported tcp transparent proxy type
- not supported tcp transparent proxy on Windows
- not supported udp transparent proxy type
- client addr must be ipv4
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/aa47af5f857f4347.
Report an issue: GitHub.