shadowsocks/shadowsocks-rust · error

not supported tcp transparent proxy on Windows

Error message

not supported tcp transparent proxy on Windows

What it means

The Windows implementation of TcpListenerRedirExt::bind_redir is a stub that unconditionally returns InvalidInput: Windows has no transparent-proxy (redirect/tproxy/pf) support in this library, so any attempt to bind a TCP redir listener on Windows fails.

Source

Thrown at crates/shadowsocks-service/src/local/redir/tcprelay/sys/windows/mod.rs:16

use std::{
    io::{self, Error, ErrorKind},
    net::SocketAddr,
};

use shadowsocks::net::AcceptOpts;
use tokio::net::{TcpListener, TcpStream};

use crate::{
    config::RedirType,
    local::redir::redir_ext::{TcpListenerRedirExt, TcpStreamRedirExt},
};

impl TcpListenerRedirExt for TcpListener {
    async fn bind_redir(_ty: RedirType, _addr: SocketAddr, _accept_opts: AcceptOpts) -> io::Result<TcpListener> {
        let err = Error::new(
            ErrorKind::InvalidInput,
            "not supported tcp transparent proxy on Windows",
        );
        Err(err)
    }
}

impl TcpStreamRedirExt for TcpStream {
    fn destination_addr(&self, _ty: RedirType) -> io::Result<SocketAddr> {
        unreachable!("not supported tcp transparent on Windows")
    }
}

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Remove the redir listener from the Windows config; use socks/http/tun inbound types instead.
  2. Use WSL2 with a Linux build if transparent proxying is required.
  3. Gate the config on OS (separate config files per platform).
  4. For whole-system proxying on Windows consider TUN mode or a system-level TUN driver.

Example fix

// before (config.json on Windows)
"locals": [{ "type": "redir", "local_address": "127.0.0.1:1081" }]
// after
"locals": [{ "type": "socks", "local_address": "127.0.0.1:1081" }]
Defensive patterns

Strategy: validation

Validate before calling

if cfg!(windows) {
    eprintln!("transparent proxy (redir) is not supported on Windows; use socks/http/tun");
    std::process::exit(2);
}

Type guard

fn redir_supported() -> bool { !cfg!(windows) }

Try / catch

if let Err(e) = bind_redir(ty, addr, accept_opts).await {
    if cfg!(windows) {
        // fall back to a SOCKS listener on Windows
        return bind_socks(addr, accept_opts).await;
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Starting a shadowsocks local server on Windows with a redir (`type: redir`) inbound listener configured; bind_redir is called and immediately errors regardless of the RedirType passed.

Common situations: Reusing a Linux/macOS redir config on Windows, or scripts that launch the same local config on all developer machines.

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