cloudflare/pingora · error

non-pathname unix sockets not supported as peer

Error message

non-pathname unix sockets not supported as peer

What it means

check_fd_match() validates that a pooled connection's file descriptor still points at the expected peer before reuse (called from HttpPeer::connection_reused/verify in pingora-core/src/upstreams/peer.rs). For Unix-domain peers pingora only supports pathname-bound sockets: it calls as_pathname() and expects Some(path). Abstract sockets (Linux '@name' addresses) and unnamed sockets return None, so the reuse check panics instead of returning false.

Source

Thrown at pingora-core/src/protocols/mod.rs:300

use log::{debug, error};
#[cfg(unix)]
use nix::sys::socket::{getpeername, SockaddrStorage, UnixAddr};
#[cfg(unix)]
use std::os::unix::prelude::AsRawFd;
#[cfg(windows)]
use std::os::windows::io::AsRawSocket;
use std::{net::SocketAddr as InetSocketAddr, path::Path};

use crate::protocols::tls::TlsRef;

#[cfg(unix)]
impl ConnFdReusable for SocketAddr {
    fn check_fd_match<V: AsRawFd>(&self, fd: V) -> bool {
        match self {
            SocketAddr::Inet(addr) => addr.check_fd_match(fd),
            SocketAddr::Unix(addr) => addr
                .as_pathname()
                .expect("non-pathname unix sockets not supported as peer")
                .check_fd_match(fd),
        }
    }
}

#[cfg(windows)]
impl ConnSockReusable for SocketAddr {
    fn check_sock_match<V: AsRawSocket>(&self, sock: V) -> bool {
        match self {
            SocketAddr::Inet(addr) => addr.check_sock_match(sock),
        }
    }
}

#[cfg(unix)]
impl ConnFdReusable for Path {
    fn check_fd_match<V: AsRawFd>(&self, fd: V) -> bool {
        let fd = fd.as_raw_fd();

View on GitHub (pinned to 0046038bd4)

Solutions

  1. Bind the upstream socket to a real filesystem path (pathname unix socket) — abstract sockets are explicitly unsupported for this check
  2. If the peer must stay abstract, disable connection reuse for that upstream so check_fd_match is never called
  3. Propose or patch pingora to return false (no match, no reuse) for non-pathname peers instead of expecting Some — failing the reuse check closed is safe

Example fix

// before: abstract-namespace peer (leading NUL / '@' form) — panics on reuse check
let peer = HttpPeer::new(SocketAddr::Unix(PathBuf::from("\0svc.sock")), true);

// after: pathname-bound unix socket, supported by pingora's fd-reuse check
let peer = HttpPeer::new(SocketAddr::Unix(PathBuf::from("/run/svc/svc.sock")), true);
Defensive patterns

Strategy: validation

Validate before calling

use std::os::unix::net::SocketAddr;

// Run before configuring the upstream peer
fn is_supported_unix_peer(addr: &SocketAddr) -> bool {
    match addr {
        SocketAddr::Unix(u) => u.as_pathname().is_some(), // pathname-bound only
        SocketAddr::Inet(_) => true,
    }
}

assert!(is_supported_unix_peer(&unix_peer_addr),
    "abstract/unnamed unix sockets are unsupported as pingora peers");

Type guard

fn is_pathname_unix(addr: &std::os::unix::net::SocketAddr) -> bool {
    matches!(addr, std::os::unix::net::SocketAddr::Unix(_))
        && addr.as_pathname().is_some() // false for abstract ('@name') and unnamed sockets
}

Prevention

When it happens

Trigger: An upstream/peer configured with a Unix SocketAddr that is abstract (path starting with a NUL byte) or unnamed, which then goes through connection-reuse validation via check_fd_match. The panic fires late — during pooled-connection reuse checks, not at connect time.

Common situations: Pointing an upstream at an abstract-namespace unix socket (used by some daemons to avoid filesystem cleanup); migrating an upstream from a path socket to an abstract socket; peers whose address comes from getpeername() on an abstract socket.

Related errors


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