{"record":{"id":"d1f81a95a830d9f5","repo":"shadowsocks/shadowsocks-rust","slug":"bind-local-addr-is-not-a-valid-ipv4-mapped-ipv6-ad","errorCode":null,"errorMessage":"bind_local_addr is not a valid IPv4-mapped IPv6 address","messagePattern":"bind_local_addr is not a valid IPv4-mapped IPv6 address","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks/src/net/sys/mod.rs","lineNumber":40,"sourceCode":"}\n\nfn set_common_sockopt_for_connect(addr: SocketAddr, socket: &TcpSocket, opts: &ConnectOpts) -> io::Result<()> {\n    // Binds to IP address\n    if let Some(baddr) = opts.bind_local_addr {\n        match (baddr, addr) {\n            (SocketAddr::V4(..), SocketAddr::V4(..)) => {\n                socket.bind(baddr)?;\n            }\n            (SocketAddr::V4(v4baddr), SocketAddr::V6(..)) => {\n                socket.bind(SocketAddr::new(v4baddr.ip().to_ipv6_mapped().into(), v4baddr.port()))?;\n            }\n            (SocketAddr::V6(..), SocketAddr::V6(..)) => {\n                socket.bind(baddr)?;\n            }\n            (SocketAddr::V6(v6baddr), SocketAddr::V4(..)) => match v6baddr.ip().to_ipv4_mapped() {\n                Some(v4baddr) => socket.bind(SocketAddr::new(v4baddr.into(), v6baddr.port()))?,\n                None => {\n                    return Err(io::Error::new(\n                        ErrorKind::InvalidInput,\n                        \"bind_local_addr is not a valid IPv4-mapped IPv6 address\",\n                    ));\n                }\n            },\n        }\n    }\n\n    // Set `SO_SNDBUF`\n    if let Some(buf_size) = opts.tcp.send_buffer_size {\n        socket.set_send_buffer_size(buf_size)?;\n    }\n\n    // Set `SO_RCVBUF`\n    if let Some(buf_size) = opts.tcp.recv_buffer_size {\n        socket.set_recv_buffer_size(buf_size)?;\n    }\n","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks/src/net/sys/mod.rs#L22-L58","documentation":"set_common_sockopt_for_connect binds the socket to bind_local_addr before connecting. When the remote target is IPv4 but bind_local_addr is an IPv6 address, shadowsocks converts it to an IPv4-mapped form; if the IPv6 address is not actually of the ::ffff:a.b.c.d mapped form, the bind cannot proceed and ErrorKind::InvalidInput is returned.","triggerScenarios":"Calling connect or connect_with_socket with a config whose bind_local_addr is an IPv6 address that is not IPv4-mapped (e.g. ::1 or 2001:db8::1) while the resolved destination address is IPv4.","commonSituations":"Users set bind_local_addr to a plain IPv6 loopback or global IPv6 address while the server address resolves to IPv4 (A record); dual-stack confusion where the outbound connection goes over IPv4.","solutions":["Set bind_local_addr to an IPv4 address (e.g. 0.0.0.0 or a specific local IPv4) when the destination is IPv4","Use an IPv4-mapped IPv6 address (::ffff:x.x.x.x) if an IPv6-form bind address is required","Remove bind_local_addr from the config so the OS picks the local address automatically","Match bind_local_addr family to the server address family (check DNS resolution result first)"],"exampleFix":"// before\nbind_local_addr = \"::1:1080\"  // plain IPv6, destination is IPv4\n// after\nbind_local_addr = \"0.0.0.0:1080\"  // IPv4 bind for IPv4 destination","handlingStrategy":"validation","validationCode":"if let SocketAddr::V6(v6) = bind_local_addr {\n    if v6.ip().to_ipv4_mapped().is_none() && dst.is_ipv4() {\n        bail!(\"bind_local_addr must be IPv4 or IPv4-mapped for IPv4 destinations\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Align bind_local_addr family with the server address family","Prefer omitting bind_local_addr and letting the OS route","Use ::ffff: literals when IPv6 notation is required for IPv4 targets"],"tags":["ipv6","bind","sockopt","shadowsocks"],"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"}