shadowsocks/shadowsocks-rust · error
`tcp_redir` invalid
Error message
`tcp_redir` invalid
What it means
Raised under the `local-redir` feature when the `tcp_redir` string in a local entry cannot be parsed into a `RedirType`. RedirType names the platform TCP redirect mechanism (e.g. iptables/redirect on Linux, pf on BSD/macOS); an unknown value is rejected as Malformed.
Source
Thrown at crates/shadowsocks-service/src/config.rs:1952
let err =
Error::new(ErrorKind::Malformed, "`forward_port` cannot be missing or 0", None);
return Err(err);
}
Some(p) => p,
};
local_config.forward_addr = Some(match forward_address.parse::<IpAddr>() {
Ok(ip) => Address::from(SocketAddr::new(ip, forward_port)),
Err(..) => Address::from((forward_address, forward_port)),
});
}
#[cfg(feature = "local-redir")]
if let Some(tcp_redir) = local.tcp_redir {
match tcp_redir.parse::<RedirType>() {
Ok(r) => local_config.tcp_redir = r,
Err(..) => {
let err = Error::new(ErrorKind::Malformed, "`tcp_redir` invalid", None);
return Err(err);
}
}
}
#[cfg(feature = "local-redir")]
if let Some(udp_redir) = local.udp_redir {
match udp_redir.parse::<RedirType>() {
Ok(r) => local_config.udp_redir = r,
Err(..) => {
let err = Error::new(ErrorKind::Malformed, "`udp_redir` invalid", None);
return Err(err);
}
}
}
#[cfg(feature = "local-dns")]
if let Some(local_dns_address) = local.local_dns_address {View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Use a RedirType value valid for your platform and build (e.g. "redirect" or "tproxy" on Linux with the matching feature enabled; "pf" on macOS/BSD).
- Remove `tcp_redir` to use the platform default.
- Check shadowsocks-rust docs for RedirType variants per OS and enabled cargo features.
Example fix
// before
{ "tcp_redir": "nftables" }
// after
{ "tcp_redir": "tproxy" } Defensive patterns
Strategy: validation
Validate before calling
fn validate_tcp_redir(entry: &serde_json::Value, platform: &str) -> Result<(), String> {
if let Some(r) = entry.get("tcp_redir").and_then(|v| v.as_str()) {
let ok = match platform {
"linux" => matches!(r, "redirect" | "tproxy"),
"macos" | "freebsd" | "openbsd" => r == "pf",
_ => false,
};
if !ok {
return Err(format!("tcp_redir '{r}' not valid for {platform}"));
}
}
Ok(())
} Try / catch
#[cfg(feature = "local-redir")]
match LocalConfig::load_from(config_path) {
Ok(cfg) => start(cfg),
Err(e) if e.to_string().contains("tcp_redir") => {
eprintln!("Bad tcp_redir for this platform/build: {e}");
std::process::exit(1);
}
Err(e) => return Err(e.into()),
} Prevention
- Keep platform-specific redir values in separate per-OS config files.
- Verify the redir backend feature is compiled into your binary before referencing it.
- Use the platform default by omitting tcp_redir unless you need a specific mechanism.
When it happens
Trigger: A config entry contains `tcp_redir` set to a string not recognized by RedirType::from_str — e.g. `"nftables"` on a version that doesn't support it, `"iptables"` on a macOS build, or a typo.
Common situations: Cross-platform configs reused on an OS whose RedirType variants differ; feature builds compiled without the redir backend matching the config; typos like "REDIRECT" or "pf" vs "pf"-style names.
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
- `udp_redir` invalid
- `local_dns_address` invalid
- `protocol` invalid
- `local_port` cannot be 0
- `local_udp_port` cannot be 0
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/76bf86b1fff9c53a.
Report an issue: GitHub.