shadowsocks/shadowsocks-rust · error

not supported udp transparent proxy type

Error message

not supported udp transparent proxy type

What it means

On macOS, UDP transparent proxy support is absent, so UdpRedirSocket::bind rejects only RedirType::NotSupported with InvalidInput; effectively every meaningful tproxy type yields this error unless a supported value exists on that platform.

Source

Thrown at crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/macos.rs:44

impl UdpRedirSocket {
    /// Create a new UDP socket binded to `addr`
    ///
    /// This will allow listening to `addr` that is not in local host
    pub fn listen(ty: RedirType, addr: SocketAddr) -> io::Result<UdpRedirSocket> {
        UdpRedirSocket::bind(ty, addr, false)
    }

    /// Create a new UDP socket binded to `addr`
    ///
    /// This will allow binding to `addr` that is not in local host
    pub fn bind_nonlocal(ty: RedirType, addr: SocketAddr, _: &RedirSocketOpts) -> io::Result<UdpRedirSocket> {
        UdpRedirSocket::bind(ty, addr, true)
    }

    fn bind(ty: RedirType, addr: SocketAddr, reuse_port: bool) -> io::Result<UdpRedirSocket> {
        if ty == RedirType::NotSupported {
            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() {
                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

  1. Disable the UDP transparent proxy relay on macOS (TCP redir is supported, UDP tproxy is not)
  2. Use the tun-based local server instead of redir if UDP proxying is needed on macOS
  3. Guard platform-specific code so UDP redir sockets are only created on platforms with a supported RedirType
  4. Check the resolved RedirType at startup and fail fast with a clear config error rather than at bind time

Example fix

// before
UdpRedirSocket::bind_nonlocal(ty, addr, &opts)?; // ty == NotSupported on macOS
// after
if cfg!(target_os = "macos") { skip_udp_redir(); } else { UdpRedirSocket::bind_nonlocal(ty, addr, &opts)?; }
Defensive patterns

Strategy: validation

Validate before calling

#[cfg(target_os = "macos")]
if ty == RedirType::NotSupported { skip_udp_relay(); }

Type guard

fn udp_redir_available(ty: RedirType) -> bool { ty != RedirType::NotSupported }

Try / catch

match UdpRedirSocket::bind_nonlocal(ty, addr, &opts) { Err(e) if e.kind()==InvalidInput => eprintln!("UDP redir unsupported here"), r => r? }

Prevention

When it happens

Trigger: Calling UdpRedirSocket::bind/bind_nonlocal with ty == RedirType::NotSupported on macOS — typically when the configured redir type was resolved to NotSupported because macOS does not support UDP transparent proxying.

Common situations: Running the redir/tun local server on macOS with a UDP relay enabled; config copied from a Linux tproxy setup; code paths that unconditionally build a UDP redir socket.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/33dbcf5d8bdfcbad. Report an issue: GitHub.