shadowsocks/shadowsocks-rust · error
tcp-redir
Error message
tcp-redir
What it means
Under the local-redir feature, the TCP_REDIR value is parsed into a RedirType (e.g. redirect, tproxy, not-supported per platform); an unknown name makes .expect("tcp-redir") panic. Parsing is guarded so it only runs when the platform supports a TCP redirect mode at all.
Source
Thrown at src/service/local.rs:761
if let Some(udp_bind_addr) = matches.get_one::<ServerAddr>("UDP_BIND_ADDR").cloned() {
local_config.udp_addr = Some(udp_bind_addr);
}
if let Some(udp_associate_addr) = matches.get_one::<ServerAddr>("UDP_ASSOCIATE_ADDR").cloned() {
local_config.udp_associate_addr = Some(udp_associate_addr);
}
#[cfg(feature = "local-tunnel")]
if let Some(addr) = matches.get_one::<Address>("FORWARD_ADDR").cloned() {
local_config.forward_addr = Some(addr);
}
#[cfg(feature = "local-redir")]
{
if RedirType::tcp_default() != RedirType::NotSupported
&& let Some(tcp_redir) = matches.get_one::<String>("TCP_REDIR")
{
local_config.tcp_redir = tcp_redir.parse::<RedirType>().expect("tcp-redir");
}
if RedirType::udp_default() != RedirType::NotSupported
&& let Some(udp_redir) = matches.get_one::<String>("UDP_REDIR")
{
local_config.udp_redir = udp_redir.parse::<RedirType>().expect("udp-redir");
}
}
#[cfg(feature = "local-dns")]
{
use shadowsocks_service::local::dns::NameServerAddr;
use self::local_value_parser::RemoteDnsAddress;
if let Some(addr) = matches.get_one::<NameServerAddr>("LOCAL_DNS_ADDR").cloned() {
local_config.local_dns_addr = Some(addr);
}View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Use a valid RedirType for your platform: typically "redirect" or "tproxy" on Linux; check RedirType docs for the compiled feature set.
- Verify the local-redir feature and OS support before using the flag; omit --tcp-redir if redirect is unsupported.
- Log RedirType::tcp_default() in a debug build to see the accepted default for the platform.
Example fix
// before sslocal --tcp-redir tproxy ... # on a platform without tproxy // after sslocal --tcp-redir redirect ... # or omit --tcp-redir
Defensive patterns
Strategy: validation
Validate before calling
if let Some(s) = matches.get_one::<String>("TCP_REDIR") {
if s.parse::<shadowsocks::local::net::RedirType>().is_err() {
return Err(format!("invalid tcp-redir for this platform: {}", s));
}
} Try / catch
let t = s.parse::<RedirType>().unwrap_or_else(|_| {
eprintln!("invalid tcp-redir: {}", s);
std::process::exit(2);
}); Prevention
- Check platform support (RedirType::tcp_default() != NotSupported) before enabling the flag.
- Use "redirect" or "tproxy" only, spelled exactly, on Linux.
- Guard feature-dependent flags behind OS checks in deployment scripts.
When it happens
Trigger: Running sslocal with --tcp-redir set to a value RedirType::from_str doesn't recognize on this platform — e.g. "tproxy" on a build/platform where only "redirect" is valid, or misspelled names like "tpproxy".
Common situations: Copying Linux tproxy examples onto a macOS/BSD build; feature flags compiled out; case/typo errors; using names from other proxy tools (e.g. "nftables").
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- plugin-mode must be one of `tcp_only` (default), `udp_only`
- udp-redir
- method
- `method` is required
- method
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/8f32e9ba77177ba0.
Report an issue: GitHub.