{"record":{"id":"f93ebdf8008d92e1","repo":"shadowsocks/shadowsocks-rust","slug":"invalid-ipv6-address-f93ebd","errorCode":null,"errorMessage":"Invalid IPv6 address","messagePattern":"Invalid IPv6 address","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks/src/net/sys/windows/mod.rs","lineNumber":473,"sourceCode":"    };\n    if !allow_fragmentation && let Err(err) = set_disable_ip_fragmentation(addr_family, &socket) {\n        warn!(\"failed to disable IP fragmentation, error: {}\", err);\n    }\n    disable_connection_reset(&socket)?;\n\n    Ok(socket)\n}\n\n/// Create a `UdpSocket` for connecting to `addr`\n#[inline(always)]\npub async fn create_outbound_udp_socket(af: AddrFamily, opts: &ConnectOpts) -> io::Result<UdpSocket> {\n    let bind_addr = match (af, opts.bind_local_addr) {\n        (AddrFamily::Ipv4, Some(SocketAddr::V4(addr))) => addr.into(),\n        (AddrFamily::Ipv4, Some(SocketAddr::V6(addr))) => {\n            // Map IPv6 bind_local_addr to IPv4 if AF is IPv4\n            match addr.ip().to_ipv4_mapped() {\n                Some(addr) => SocketAddr::new(addr.into(), 0),\n                None => return Err(io::Error::new(ErrorKind::InvalidInput, \"Invalid IPv6 address\")),\n            }\n        }\n        (AddrFamily::Ipv6, Some(SocketAddr::V6(addr))) => addr.into(),\n        (AddrFamily::Ipv6, Some(SocketAddr::V4(addr))) => {\n            // Map IPv4 bind_local_addr to IPv6 if AF is IPv6\n            SocketAddr::new(addr.ip().to_ipv6_mapped().into(), 0)\n        }\n        (AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),\n        (AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),\n    };\n\n    bind_outbound_udp_socket(&bind_addr, opts).await\n}\n\n/// Create a `UdpSocket` binded to `bind_addr`\npub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, opts: &ConnectOpts) -> io::Result<UdpSocket> {\n    let af = AddrFamily::from(bind_addr);\n","sourceCodeStart":455,"sourceCodeEnd":491,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks/src/net/sys/windows/mod.rs#L455-L491","documentation":"Identical logic to the Unix variant: when creating an outbound UDP socket with IPv4 address family but a bind_local_addr that is an IPv6 address, only IPv4-mapped IPv6 addresses can be converted down to IPv4. A non-mapped IPv6 address (like \"::\" or a global IPv6 addr) cannot serve as an IPv4 bind address, so create_outbound_udp_socket returns ErrorKind::InvalidInput with \"Invalid IPv6 address\".","triggerScenarios":"create_outbound_udp_socket on Windows with AddrFamily::Ipv4 and opts.bind_local_addr set to a non-IPv4-mapped IPv6 SocketAddr, e.g. bind_local_addr = \"::\" while the remote server is reached over IPv4.","commonSituations":"Config with bind_address = \"::\" intending dual-stack, but remote resolves to IPv4; reusing an IPv6 bind config for an IPv4 server; environment where Windows chooses IPv4 for the outbound route.","solutions":["Set bind_local_addr to an IPv4 address (e.g. \"0.0.0.0\") for IPv4 outbound sockets","Use an IPv4-mapped IPv6 literal (\"::ffff:0.0.0.0\") if you want to express IPv4-any in v6 form","Remove bind_local_addr entirely to let the OS pick the source address","Make the bind address family consistent with the server address family in your config"],"exampleFix":"# before\nbind_address = \"::\"\n# after\nbind_address = \"0.0.0.0\"  # matches IPv4 outbound","handlingStrategy":"validation","validationCode":"fn bind_compatible(af: shadowsocks::net::AddrFamily, bind: Option<std::net::SocketAddr>) -> bool {\n    match (af, bind) {\n        (shadowsocks::net::AddrFamily::Ipv4, Some(std::net::SocketAddr::V6(v6))) => v6.ip().to_ipv4_mapped().is_some(),\n        _ => true,\n    }\n}\nassert!(bind_compatible(AddrFamily::Ipv4, opts.bind_local_addr), \"bind_local_addr must be IPv4 or IPv4-mapped for Ipv4 outbound\");","typeGuard":"fn is_ipv4_usable(addr: &std::net::SocketAddr) -> bool {\n    match addr {\n        std::net::SocketAddr::V4(_) => true,\n        std::net::SocketAddr::V6(v6) => v6.ip().to_ipv4_mapped().is_some(),\n    }\n}","tryCatchPattern":"match create_outbound_udp_socket(context, AddrFamily::Ipv4, &opts).await {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains(\"Invalid IPv6\") => {\n        let mut fixed = opts.clone();\n        fixed.bind_local_addr = Some(\"0.0.0.0:0\".parse().unwrap());\n        create_outbound_udp_socket(context, AddrFamily::Ipv4, &fixed).await\n    }\n    r => r,\n}","preventionTips":["Align bind_local_addr family with the server address family in the same config","Use \"0.0.0.0\" instead of \"::\" when the remote is IPv4","Omit bind_local_addr unless source binding is explicitly required","Add a config lint step for family mismatch on Windows hosts"],"tags":["windows","ipv6","udp","bind","config"],"backgroundTag":"invalid-config-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"}