{"record":{"id":"ce9a8fed6b19df5e","repo":"shadowsocks/shadowsocks-rust","slug":"not-supported-tcp-transparent-proxy-type-ce9a8f","errorCode":null,"errorMessage":"not supported tcp transparent proxy type","messagePattern":"not supported tcp transparent proxy type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/local/redir/tcprelay/sys/unix/linux.rs","lineNumber":90,"sourceCode":"                } else {\n                    // bind, listen as original\n                    socket.bind(addr)?;\n                }\n\n                // mio's default backlog is 1024\n                let listener = socket.listen(1024)?;\n\n                if accept_opts.tcp.fastopen {\n                    set_tcp_fastopen(&listener)?;\n                }\n\n                Ok(listener)\n            }\n            RedirType::TProxy => {\n                // TPROXY rule requires IP_TRANSPARENT\n                create_redir_listener(addr, accept_opts).await\n            }\n            _ => Err(Error::new(\n                ErrorKind::InvalidInput,\n                \"not supported tcp transparent proxy type\",\n            )),\n        }\n    }\n}\n\nimpl TcpStreamRedirExt for TcpStream {\n    fn destination_addr(&self, ty: RedirType) -> io::Result<SocketAddr> {\n        match ty {\n            RedirType::Redirect => get_original_destination_addr(self),\n            RedirType::TProxy => {\n                // For TPROXY, uses getsockname() to retrieve original destination address\n                self.local_addr()\n            }\n            _ => unreachable!(\"not supported tcp transparent proxy type\"),\n        }\n    }","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/local/redir/tcprelay/sys/unix/linux.rs#L72-L108","documentation":"On Linux the TCP redir listener supports RedirType::Redirect and RedirType::TProxy only. Any other RedirType value (e.g. PacketFilter) hits the wildcard arm and bind_redir returns InvalidInput \"not supported tcp transparent proxy type\".","triggerScenarios":"Calling bind_redir on Linux with a RedirType other than Redirect or TProxy — typically a config copied from a BSD/macOS host using PacketFilter or IpFirewall.","commonSituations":"Sharing one config file across Linux and macOS hosts, typos in the redir type value, or older binaries whose enum decoding accepted a type this platform can't bind.","solutions":["Set tcp redir type to `redirect` or `tproxy` in the Linux local config.","If TProxy is desired, ensure the kernel supports TPROXY and the process has CAP_NET_ADMIN (IP_TRANSPARENT).","Use platform-conditional config files per host.","Confirm the redir type string against the supported list in the docs."],"exampleFix":"// before (config.json on Linux)\n\"tcp_redir\": \"packet-filter\"\n// after\n\"tcp_redir\": \"tproxy\"","handlingStrategy":"validation","validationCode":"#[cfg(target_os = \"linux\")]\nassert!(matches!(ty, RedirType::Redirect | RedirType::TProxy));","typeGuard":"fn is_supported_tcp_redir_linux(ty: &RedirType) -> bool {\n    matches!(ty, RedirType::Redirect | RedirType::TProxy)\n}","tryCatchPattern":"match bind_redir(ty, addr, accept_opts).await {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => {\n    eprintln!(\"unsupported redir type {ty:?} on Linux; use redirect or tproxy\");\n        std::process::exit(2);\n    }\n    r => r?,\n}","preventionTips":["Use RedirType::tcp_default() rather than a hardcoded value in code","Keep Linux and BSD configs separate","For tproxy, verify kernel TPROXY support and CAP_NET_ADMIN before startup"],"tags":["configuration","linux","transparent-proxy","unsupported-platform"],"backgroundTag":"unsupported-enum-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}