shadowsocks/shadowsocks-rust · error

invalid interface name

Error message

invalid interface name

What it means

On Windows, binding to a specific interface by name requires converting the interface name to an index via the Win32 if_nametoindex API. When that API returns 0 (name not resolvable to an interface index), the library throws ErrorKind::InvalidInput with "invalid interface name". Windows has no error code in this case, so the message is generic.

Source

Thrown at crates/shadowsocks/src/net/sys/windows/mod.rs:290

        let now = Instant::now();
        if now - insert_time < INDEX_EXPIRE_DURATION {
            return Ok(idx);
        }
    }

    // Get from API GetAdaptersAddresses
    let idx = match find_adapter_interface_index(addr, iface)? {
        Some(idx) => idx,
        None => unsafe {
            // Windows if_nametoindex requires a C-string for interface name
            let ifname = CString::new(iface).expect("iface");

            // https://docs.microsoft.com/en-us/previous-versions/windows/hardware/drivers/ff553788(v=vs.85)
            let if_index = if_nametoindex(ifname.as_ptr() as PCSTR);
            if if_index == 0 {
                // If the if_nametoindex function fails and returns zero, it is not possible to determine an error code.
                error!("if_nametoindex {} fails", iface);
                return Err(io::Error::new(ErrorKind::InvalidInput, "invalid interface name"));
            }

            if_index
        },
    };

    INTERFACE_INDEX_CACHE.with(|cache| {
        cache.borrow_mut().insert(iface.to_owned(), (idx, Instant::now()));
    });

    Ok(idx)
}

fn set_ip_unicast_if<S: AsRawSocket>(socket: &S, addr: &SocketAddr, iface: &str) -> io::Result<()> {
    let handle = socket.as_raw_socket() as SOCKET;

    let if_index = find_interface_index_cached(addr, iface)?;

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Use a Windows-valid interface name/alias (e.g. "Ethernet", "Wi-Fi") as shown by `netsh interface show interface` or `Get-NetAdapter`
  2. Alternatively specify the interface index directly instead of the name if your config supports it
  3. Verify the adapter still exists (VPN/driver changes can remove it) and update the config
  4. Prefer binding by IP address (outbound bind address) rather than interface name on Windows

Example fix

# before (config)
bind_interface = "eth0"
# after
bind_interface = "Ethernet"  # Windows adapter alias from `netsh interface show interface`
Defensive patterns

Strategy: validation

Validate before calling

// Windows: resolve the name to an index before configuring the server
fn interface_name_resolves(name: &str) -> bool {
    #[cfg(windows)]
    unsafe {
        let wide: Vec<u16> = name.encode_utf16().chain(std::iter::once(0)).collect();
        windows::Win32::NetworkManagement::IpHelper::if_nametoindex(wide.as_ptr()) != 0
    }
    #[cfg(not(windows))]
    { true }
}
assert!(interface_name_resolves(&cfg.outbound_bind_interface), "interface not found on this system");

Try / catch

match server.run().await {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains("invalid interface name") => {
        eprintln!("bind_interface '{}' not found; falling back to default routing", cfg.outbound_bind_interface);
        cfg.outbound_bind_interface = None;
        server.run().await
    }
    r => r,
}

Prevention

When it happens

Trigger: Calling set_ip_unicast_if (via interface config like outbound bind_interface) with a name that Windows cannot resolve — e.g. "eth0" (Linux-style naming), a display name like "Ethernet 2" instead of the adapter's proper alias, or an adapter that was removed/renamed.

Common situations: Porting Linux configs that use interface names like eth0/wlan0 to Windows; interface renamed after driver update; VPN adapter disappeared so its name no longer resolves; using a friendly name instead of the NetConnectionID alias.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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