{"record":{"id":"2d447ea712f9a374","repo":"cloudflare/pingora","slug":"non-pathname-unix-sockets-not-supported-as-peer","errorCode":null,"errorMessage":"non-pathname unix sockets not supported as peer","messagePattern":"non-pathname unix sockets not supported as peer","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pingora-core/src/connectors/l4.rs","lineNumber":194,"sourceCode":"                        Ok(socket) => {\n                            local_addr = connect_attempt.local_addr();\n                            debug!(\"connected to new server: {}\", peer.address());\n                            Ok(socket.into())\n                        }\n                        Err(e) => {\n                            let c = format!(\"Fail to connect to {peer}\");\n                            match e.etype() {\n                                SocketError | BindError => Error::e_because(InternalError, c, e),\n                                _ => Err(e.more_context(c)),\n                            }\n                        }\n                    }\n                }\n                #[cfg(unix)]\n                SocketAddr::Unix(addr) => {\n                    let connect_future = connect_uds(\n                        addr.as_pathname()\n                            .expect(\"non-pathname unix sockets not supported as peer\"),\n                    );\n                    let conn_res = match peer.connection_timeout() {\n                        Some(t) => pingora_timeout::timeout(t, connect_future)\n                            .await\n                            .explain_err(ConnectTimedout, |_| {\n                                format!(\"timeout {t:?} connecting to server {peer}\")\n                            })?,\n                        None => connect_future.await,\n                    };\n                    match conn_res {\n                        Ok(socket) => {\n                            debug!(\"connected to new server: {}\", peer.address());\n                            Ok(socket.into())\n                        }\n                        Err(e) => {\n                            let c = format!(\"Fail to connect to {peer}\");\n                            match e.etype() {\n                                SocketError | BindError => Error::e_because(InternalError, c, e),","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/cloudflare/pingora/blob/0046038bd402bc82912da862dadf9a479f31e9f1/pingora-core/src/connectors/l4.rs#L176-L212","documentation":"When the generic L4 connector dials a SocketAddr::Unix peer it must pass a filesystem path to connect_uds(); tokio's as_pathname() returns None for abstract or unnamed Linux sockets, and pingora .expect()s Some(path), panicking with 'non-pathname unix sockets not supported as peer'. pingora's own constructors (HttpPeer::new_uds, BasicPeer::new_uds) build addresses via UnixSocketAddr::from_pathname, so this only fires when a Peer or SocketAddr::Unix was assembled by other means with an abstract/unnamed address.","triggerScenarios":"A custom Peer implementation, or code calling HttpPeer::new_from_sockaddr/BasicPeer::new_from_sockaddr directly, supplies SocketAddr::Unix holding an abstract address (path beginning with a NUL byte, '@name' style); the first connection attempt panics inside connectors/l4.rs:194.","commonSituations":"Targeting services listening on the Linux abstract namespace (systemd-adjacent/Android-style daemons); building peers from the address of an accepted socket; custom address parsers accepting 'unix:@foo' strings.","solutions":["Use a real filesystem path: HttpPeer::new_uds(\"/run/svc.sock\", tls, sni) — from_pathname() itself rejects interior NUL bytes for you","In custom Peer impls, only ever return pathname-based Unix addresses from address()","If the target truly is an abstract socket, connect to it outside pingora's L4 connector and bridge over TCP/localhost"],"exampleFix":"// before: custom peer built from an abstract address (as_pathname() -> None)\nlet peer = HttpPeer::new_from_sockaddr(abstract_unix_peer_addr(), false, \"svc\".into());\n\n// after: a real pathname UDS peer\nlet peer = HttpPeer::new_uds(\"/run/svc.sock\", false, \"svc\".into())?;","handlingStrategy":"validation","validationCode":"// Reject abstract/unnamed UDS peers before handing them to the connector\nuse pingora_core::protocols::l4::socket::SocketAddr;\nfn ensure_pathname_peer<P: pingora_core::upstreams::peer::Peer>(peer: &P) -> Result<()> {\n    if let SocketAddr::Unix(addr) = peer.address() {\n        if addr.as_pathname().is_none() {\n            return Err(pingora_error::Error::explain(\n                pingora_error::ErrorType::InternalError,\n                \"abstract unix sockets are not supported as peers\",\n            ));\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create UDS peers only via HttpPeer::new_uds()/BasicPeer::new_uds(), which enforce pathname addresses","In custom Peer impls, construct the address with UnixSocketAddr::from_pathname() and reject '@'-prefixed or NUL-containing paths","Add an assertion in tests that every configured UDS upstream resolves to a real filesystem path"],"tags":["rust","unix-socket","abstract-socket","connector","pingora","panic"],"backgroundTag":"abstract-unix-socket-unsupported","analyzedSha":"0046038bd402bc82912da862dadf9a479f31e9f1","analyzedAt":"2026-08-16T21:33:22.341Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}