shadowsocks/shadowsocks-rust · error
udp-redir
Error message
udp-redir
What it means
Analogous to the tcp case: under the local-redir feature, UDP_REDIR is parsed into RedirType and .expect("udp-redir") panics on an unknown value. It only evaluates when the platform has a UDP-capable redirect default (tproxy on Linux; many platforms have no UDP redirect).
Source
Thrown at src/service/local.rs:767
}
#[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);
}
if let Some(addr) = matches.get_one::<RemoteDnsAddress>("REMOTE_DNS_ADDR").cloned() {
local_config.remote_dns_addr = Some(addr.0);
}
}
View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Use "tproxy" for --udp-redir on Linux; on platforms without UDP redirect, omit the flag entirely.
- Check RedirType::udp_default() != NotSupported for your build before using the flag.
- Correct typos so the string matches the RedirType FromStr implementation exactly.
Example fix
// before sslocal --udp-redir redirect ... // after sslocal --udp-redir tproxy ...
Defensive patterns
Strategy: validation
Validate before calling
if let Some(s) = matches.get_one::<String>("UDP_REDIR") {
match s.parse::<shadowsocks::local::net::RedirType>() {
Ok(t) if t != shadowsocks::local::net::RedirType::NotSupported => {}
_ => return Err(format!("udp-redir '{}' unsupported on this platform (use tproxy on Linux)", s)),
}
} Try / catch
let t = s.parse::<RedirType>().unwrap_or_else(|_| {
eprintln!("invalid udp-redir: {}", s);
std::process::exit(2);
}); Prevention
- Remember only tproxy supports UDP redirect; "redirect" is TCP-only.
- Skip --udp-redir entirely on platforms where RedirType::udp_default() is NotSupported.
- Validate redir flags in CI across the target OS matrix.
When it happens
Trigger: Passing --udp-redir with a name not valid for the platform/build, such as "redirect" (TCP-only mechanism) where only "tproxy" supports UDP, or a typo like "udtproxy".
Common situations: Assuming redirect supports UDP (it does not); enabling --udp-redir on macOS/BSD where UDP redirect is unsupported; typos and case mistakes.
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
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/c1816c95d81f4698.
Report an issue: GitHub.