shadowsocks/shadowsocks-rust · error

not supported udp transparent proxy type

Error message

not supported udp transparent proxy type

What it means

OpenBSD's UDP transparent proxy bind rejects RedirType::NotSupported with InvalidInput. Like macOS, this fires when the caller passes a type the platform cannot actually serve, guarding against silently creating a useless socket.

Source

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

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 {
            if 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. Remove or disable the UDP relay in the redir local server config on OpenBSD
  2. Ensure the RedirType parsed from config is valid for OpenBSD before binding
  3. Gate UDP redir socket creation behind platform capability checks
  4. Use divert-to/pf-based forwarding only for the types the platform supports

Example fix

// before
UdpRedirSocket::bind(RedirType::NotSupported, addr, false)?;
// after
match ty { RedirType::NotSupported => return Ok(()), _ => UdpRedirSocket::bind(ty, addr, false)? }
Defensive patterns

Strategy: validation

Validate before calling

if ty == RedirType::NotSupported { return; } // skip UDP relay on OpenBSD

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 => log::info!("udp redir not supported; disabled"), r => r? }

Prevention

When it happens

Trigger: Calling UdpRedirSocket::bind/bind_nonlocal with ty == RedirType::NotSupported on OpenBSD — usually because config resolution produced NotSupported for this platform.

Common situations: Deploying the same shadowsocks local config across BSD/Linux hosts; OpenBSD lacks the UDP tproxy mode used on Linux.

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/3dd5badb6adaba9d. Report an issue: GitHub.