shadowsocks/shadowsocks-rust · error
not supported udp transparent proxy type
Error message
not supported udp transparent proxy type
What it means
bind() on Linux UDP transparent proxy only supports RedirType::TProxy for UDP; any other RedirType (e.g. Redirect) yields InvalidInput. It is a compile-time-style runtime guard ensuring the caller picks a UDP-capable transparent proxy mode.
Source
Thrown at crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/linux.rs:63
libc::setsockopt(
socket.as_raw_fd(),
libc::SOL_SOCKET,
libc::SO_MARK,
&mark as *const _ as *const _,
mem::size_of_val(&mark) as libc::socklen_t,
)
};
if ret != 0 {
return Err(Error::last_os_error());
}
}
Ok(socket)
}
fn bind(ty: RedirType, addr: SocketAddr, reuse_port: bool) -> io::Result<Self> {
if ty != RedirType::TProxy {
return Err(Error::new(
ErrorKind::InvalidInput,
"not supported udp transparent proxy type",
));
}
let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))?;
set_socket_before_bind(&addr, &socket)?;
socket.set_nonblocking(true)?;
socket.set_reuse_address(true)?;
if reuse_port && let Err(err) = socket.set_reuse_port(true) {
if let Some(libc::ENOPROTOOPT) = err.raw_os_error() {
// SO_REUSEPORT is supported after 3.9
trace!("failed to set SO_REUSEPORT, error: {}", err);
} else {
error!("failed to set SO_REUSEPORT, error: {}", err);
return Err(err);
}View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Set the UDP transparent proxy type to 'tproxy' in the local server configuration
- Add iptables TPROXY rules (mangle table, PREROUTING with TPROXY target) so tproxy mode actually works
- If only plain redirect is available, do not instantiate the UDP relay with the redirect type
- Verify the RedirType enum value passed in comes from parsed config, not a default
Example fix
// before let ty = RedirType::Redirect; UdpRedirSocket::bind(ty, addr, false)?; // after let ty = RedirType::TProxy; // UDP on Linux requires tproxy UdpRedirSocket::bind(ty, addr, false)?;
Defensive patterns
Strategy: validation
Validate before calling
if redir_type != RedirType::TProxy {
return Err("Linux UDP transparent proxy requires redir-type=tproxy");
} Type guard
fn udp_supported(ty: RedirType) -> bool { matches!(ty, RedirType::TProxy) } Try / catch
match UdpRedirSocket::bind(ty, addr, reuse) { Err(e) if e.kind()==InvalidInput => bail!("configure udp redir-type=tproxy"), r => r } Prevention
- Set redir-type=tproxy for UDP on Linux
- Validate config RedirType at startup
- Install iptables TPROXY rules before starting the server
- Keep TCP (redirect) and UDP (tproxy) types separate in config
When it happens
Trigger: Calling UdpRedirSocket::bind (directly or via bind_nonlocal) with ty set to anything other than RedirType::TProxy on Linux — typically because the config's udp redir type was set to 'redirect' or left as NotSupported.
Common situations: Configuring the local redir server with redir-type=redirect for TCP but reusing the same type for UDP; on Linux UDP requires tproxy (TPROXY iptables rules).
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
- missing destination address in msghdr
- redir destination must not be an domain name address
- missing destination address in msghdr
- not supported udp transparent proxy type
- not supported udp transparent proxy type
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/dbf81bbd776680a5.
Report an issue: GitHub.