cloudflare/pingora · error · std::io::Error
invalid argument
Error message
invalid argument
What it means
On Windows, pingora converts the raw Winsock sockaddr storage returned by getpeername/getsockname into std::net::SocketAddr via sockaddr_to_addr() in protocols/windows.rs. Only AF_INET and AF_INET6 are handled; every other address family is rejected with io::Error::new(ErrorKind::InvalidInput, "invalid argument"). It surfaces through peer_addr()/local_addr() of pingora streams and listeners on Windows builds.
Source
Thrown at pingora-core/src/protocols/windows.rs:83
match storage.ss_family {
AF_INET => {
assert!(len >= mem::size_of::<SOCKADDR_IN>());
Ok(SocketAddr::from(unsafe {
let sockaddr = *(storage as *const _ as *const SOCKADDR_IN);
(
sockaddr.sin_addr.S_un.S_addr.to_ne_bytes(),
sockaddr.sin_port.to_be(),
)
}))
}
AF_INET6 => {
assert!(len >= mem::size_of::<SOCKADDR_IN6>());
Ok(SocketAddr::from(unsafe {
let sockaddr = *(storage as *const _ as *const SOCKADDR_IN6);
(sockaddr.sin6_addr.u.Byte, sockaddr.sin6_port.to_be())
}))
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"invalid argument",
)),
}
}
#[cfg(test)]
mod tests {
use std::os::windows::io::AsRawSocket;
use crate::protocols::l4::{listener::Listener, stream::Stream};
use super::*;
async fn assert_listener_and_stream(addr: &str) {
let tokio_listener = tokio::net::TcpListener::bind(addr).await.unwrap();
let listener_local_addr = tokio_listener.local_addr().unwrap();View on GitHub (pinned to 0046038bd4)
Solutions
- Restrict pingora on Windows to IPv4/IPv6 TCP listeners and upstreams, which is the supported configuration
- Match ErrorKind::InvalidInput from peer_addr()/local_addr() and drop the unsupported connection instead of unwrapping
- Terminate non-INET transports outside pingora and bridge them to pingora over TCP/localhost
Example fix
// before
let peer = stream.peer_addr()?; // InvalidInput for non-INET families on Windows
// after
let peer = match stream.peer_addr() {
Ok(a) => a,
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => {
return Ok(()); // unsupported address family: drop connection
}
Err(e) => return Err(e.into()),
}; Defensive patterns
Strategy: try-catch
Try / catch
// Windows: tolerate unsupported socket families from peer_addr()/local_addr()
match stream.peer_addr() {
Ok(addr) => { /* proceed */ }
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => {
log::warn!("dropping connection with unsupported address family");
return Ok(()); // skip the connection, do not abort the accept loop
}
Err(e) => return Err(e.into()),
} Prevention
- On Windows, bind only IPv4/IPv6 listeners and never hand non-INET sockets to pingora's l4 layer
- Never unwrap() peer_addr()/local_addr() in accept paths; map InvalidInput to a controlled 'drop connection' branch
- Run a Windows CI job so platform-specific address handling is exercised before release
When it happens
Trigger: Running pingora on Windows and calling peer_addr()/local_addr() on a socket whose family is neither AF_INET nor AF_INET6, e.g. a Windows AF_UNIX socket or other non-TCP transport handed to pingora's l4 accept path.
Common situations: Experimental Windows builds trying AF_UNIX (supported since Windows 10 17063) through pingora's TCP-centric layer; unit tests on Windows that create exotic sockets; in normal HTTP proxying this is nearly unreachable because peers are always IPv4/IPv6.
Related errors
- No tls feature was specified
- non-pathname unix sockets not supported as peer
- Tried to listen with no addr specified
- failed to build offload runtime
- failed to spawn offload runtime thread
AI-assisted analysis of cloudflare/pingora@0046038bd4 (2026-08-16).
Data as JSON: /api/errors/b916b8700a55f642.
Report an issue: GitHub.