shadowsocks/shadowsocks-rust · error
Invalid IPv6 address
Error message
Invalid IPv6 address
What it means
create_outbound_udp_socket on Linux binds to config.bind_local_addr when present. If the socket address family is IPv4 but bind_local_addr is IPv6, the code converts it via to_ipv4_mapped(); a non-mapped IPv6 address cannot be converted, so the call returns ErrorKind::InvalidInput with this message.
Source
Thrown at crates/shadowsocks/src/net/sys/unix/linux/mod.rs:283
if ret < 0 {
return Err(io::Error::last_os_error());
}
}
}
Ok(())
}
/// Create a `UdpSocket` with specific address family
#[inline]
pub async fn create_outbound_udp_socket(af: AddrFamily, config: &ConnectOpts) -> io::Result<UdpSocket> {
let bind_addr = match (af, config.bind_local_addr) {
(AddrFamily::Ipv4, Some(SocketAddr::V4(addr))) => addr.into(),
(AddrFamily::Ipv4, Some(SocketAddr::V6(addr))) => {
// Map IPv6 bind_local_addr to IPv4 if AF is IPv4
match addr.ip().to_ipv4_mapped() {
Some(addr) => SocketAddr::new(addr.into(), 0),
None => return Err(io::Error::new(ErrorKind::InvalidInput, "Invalid IPv6 address")),
}
}
(AddrFamily::Ipv6, Some(SocketAddr::V6(addr))) => addr.into(),
(AddrFamily::Ipv6, Some(SocketAddr::V4(addr))) => {
// Map IPv4 bind_local_addr to IPv6 if AF is IPv6
SocketAddr::new(addr.ip().to_ipv6_mapped().into(), 0)
}
(AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),
(AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),
};
bind_outbound_udp_socket(&bind_addr, config).await
}
/// Create a `UdpSocket` binded to `bind_addr`
pub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, config: &ConnectOpts) -> io::Result<UdpSocket> {
let af = AddrFamily::from(bind_addr);
View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Use an IPv4 bind_local_addr when the outbound family is IPv4
- Use an IPv4-mapped IPv6 literal (e.g. ::ffff:10.0.0.5) if IPv6 notation is needed
- Remove bind_local_addr to let the OS choose the source address
- Match bind_local_addr family to the destination family before creating the socket
Example fix
// before
config.set_bind_local_addr("2001:db8::1:1080".parse().unwrap());
// after
config.set_bind_local_addr("0.0.0.0:1080".parse().unwrap()); Defensive patterns
Strategy: validation
Validate before calling
if let Some(SocketAddr::V6(v6)) = config.bind_local_addr {
if af == AddrFamily::Ipv4 && v6.ip().to_ipv4_mapped().is_none() {
bail!("bind_local_addr not mappable to IPv4");
}
} Prevention
- Use IPv4 bind addresses for IPv4 destinations
- Let the OS choose source address by leaving bind_local_addr unset
- Validate config address families at startup, before socket creation
When it happens
Trigger: Calling create_outbound_udp_socket with AddrFamily::Ipv4 while ServerConfig.bind_local_addr is Some(SocketAddr::V6(addr)) whose IP is not an IPv4-mapped IPv6 address.
Common situations: Setting bind_local_addr to a plain IPv6 address (e.g. :: or 2001:db8::1) while connecting to an IPv4 UDP server; configs copied from IPv6-only setups.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Invalid IPv6 address
- Invalid IPv6 address
- Invalid IPv6 address
- Invalid IPv6 address
- not supported udp transparent proxy type
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/b5cfc9079363ccf3.
Report an issue: GitHub.