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

  1. Restrict pingora on Windows to IPv4/IPv6 TCP listeners and upstreams, which is the supported configuration
  2. Match ErrorKind::InvalidInput from peer_addr()/local_addr() and drop the unsupported connection instead of unwrapping
  3. 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

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


AI-assisted analysis of cloudflare/pingora@0046038bd4 (2026-08-16). Data as JSON: /api/errors/b916b8700a55f642. Report an issue: GitHub.