{"record":{"id":"fb1bddf079643a2d","repo":"shadowsocks/shadowsocks-rust","slug":"invalid-interface-name","errorCode":null,"errorMessage":"invalid interface name","messagePattern":"invalid interface name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks/src/net/sys/windows/mod.rs","lineNumber":290,"sourceCode":"        let now = Instant::now();\n        if now - insert_time < INDEX_EXPIRE_DURATION {\n            return Ok(idx);\n        }\n    }\n\n    // Get from API GetAdaptersAddresses\n    let idx = match find_adapter_interface_index(addr, iface)? {\n        Some(idx) => idx,\n        None => unsafe {\n            // Windows if_nametoindex requires a C-string for interface name\n            let ifname = CString::new(iface).expect(\"iface\");\n\n            // https://docs.microsoft.com/en-us/previous-versions/windows/hardware/drivers/ff553788(v=vs.85)\n            let if_index = if_nametoindex(ifname.as_ptr() as PCSTR);\n            if if_index == 0 {\n                // If the if_nametoindex function fails and returns zero, it is not possible to determine an error code.\n                error!(\"if_nametoindex {} fails\", iface);\n                return Err(io::Error::new(ErrorKind::InvalidInput, \"invalid interface name\"));\n            }\n\n            if_index\n        },\n    };\n\n    INTERFACE_INDEX_CACHE.with(|cache| {\n        cache.borrow_mut().insert(iface.to_owned(), (idx, Instant::now()));\n    });\n\n    Ok(idx)\n}\n\nfn set_ip_unicast_if<S: AsRawSocket>(socket: &S, addr: &SocketAddr, iface: &str) -> io::Result<()> {\n    let handle = socket.as_raw_socket() as SOCKET;\n\n    let if_index = find_interface_index_cached(addr, iface)?;\n","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks/src/net/sys/windows/mod.rs#L272-L308","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use a Windows-valid interface name/alias (e.g. \"Ethernet\", \"Wi-Fi\") as shown by `netsh interface show interface` or `Get-NetAdapter`","Alternatively specify the interface index directly instead of the name if your config supports it","Verify the adapter still exists (VPN/driver changes can remove it) and update the config","Prefer binding by IP address (outbound bind address) rather than interface name on Windows"],"exampleFix":"# before (config)\nbind_interface = \"eth0\"\n# after\nbind_interface = \"Ethernet\"  # Windows adapter alias from `netsh interface show interface`","handlingStrategy":"validation","validationCode":"// Windows: resolve the name to an index before configuring the server\nfn interface_name_resolves(name: &str) -> bool {\n    #[cfg(windows)]\n    unsafe {\n        let wide: Vec<u16> = name.encode_utf16().chain(std::iter::once(0)).collect();\n        windows::Win32::NetworkManagement::IpHelper::if_nametoindex(wide.as_ptr()) != 0\n    }\n    #[cfg(not(windows))]\n    { true }\n}\nassert!(interface_name_resolves(&cfg.outbound_bind_interface), \"interface not found on this system\");","typeGuard":null,"tryCatchPattern":"match server.run().await {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains(\"invalid interface name\") => {\n        eprintln!(\"bind_interface '{}' not found; falling back to default routing\", cfg.outbound_bind_interface);\n        cfg.outbound_bind_interface = None;\n        server.run().await\n    }\n    r => r,\n}","preventionTips":["Use Windows adapter aliases (from `netsh interface show interface`), not Linux-style names like eth0","Re-resolve adapter names after driver updates or VPN adapter changes","Prefer binding by local IP address instead of interface name for portability","Detect the platform at config-generation time and emit platform-appropriate interface names"],"tags":["windows","network-interface","bind","configuration"],"backgroundTag":"invalid-argument-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}