{"record":{"id":"06b4ceae38e125b7","repo":"block/buzz","slug":"failed-to-bind-uds-uds-path-e","errorCode":null,"errorMessage":"Failed to bind UDS {uds_path}: {e}","messagePattern":"Failed to bind UDS (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"crates/buzz-relay/src/main.rs","lineNumber":1466,"sourceCode":"        .map_err(|e| anyhow::anyhow!(\"Failed to bind {}: {e}\", config.bind_addr))?;\n    info!(addr = %config.bind_addr, \"buzz-relay TCP listening\");\n\n    #[cfg(unix)]\n    if let Some(ref uds_path) = config.uds_path {\n        use std::os::unix::fs::FileTypeExt as _;\n        match std::fs::symlink_metadata(uds_path) {\n            Ok(meta) if meta.file_type().is_socket() => {\n                let _ = std::fs::remove_file(uds_path);\n            }\n            Ok(_) => {\n                return Err(anyhow::anyhow!(\n                    \"BUZZ_UDS_PATH {uds_path} exists but is not a socket\"\n                ));\n            }\n            Err(_) => {}\n        }\n        let uds_listener = tokio::net::UnixListener::bind(uds_path)\n            .map_err(|e| anyhow::anyhow!(\"Failed to bind UDS {uds_path}: {e}\"))?;\n        info!(path = %uds_path, \"buzz-relay UDS listening\");\n\n        let router_uds = router.clone();\n        let mut uds_rx = shutdown_tx.subscribe();\n        let uds_handle = tokio::spawn(async move {\n            axum::serve(uds_listener, router_uds.into_make_service())\n                .with_graceful_shutdown(async move {\n                    uds_rx.changed().await.ok();\n                })\n                .await\n                .ok();\n        });\n\n        let mut tcp_rx = shutdown_tx.subscribe();\n        axum::serve(\n            tcp_listener,\n            router.into_make_service_with_connect_info::<std::net::SocketAddr>(),\n        )","sourceCodeStart":1448,"sourceCodeEnd":1484,"githubUrl":"https://github.com/block/buzz/blob/ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be/crates/buzz-relay/src/main.rs#L1448-L1484","documentation":"After the stale-socket cleanup in serve(), tokio::net::UnixListener::bind(uds_path) creates the actual Unix domain socket. Failure is wrapped with the path and aborts boot. Common causes are filesystem-level: missing or non-writable parent directory, path components denying search/execute permission, a path longer than the kernel's sun_path limit (~104-108 bytes), or a read-only filesystem.","triggerScenarios":"UnixListener::bind at crates/buzz-relay/src/main.rs:1349 fails with EACCES (parent dir owned by root, relay running as non-root), ENOENT (parent directory does not exist), ENAMETOOLONG/EINVAL (BUZZ_UDS_PATH longer than the ~108-byte sun_path limit, typical with deeply nested /var/run/very/long/service/name.sock paths), or EROFS (path under a read-only mount).","commonSituations":"Running the relay as an unprivileged user with BUZZ_UDS_PATH=/var/run/buzz.sock (root-owned /var/run); long namespaced paths under /run/user/1000/... in deeply nested worktrees; SELinux denying socket creation in the target directory; container with a read-only rootfs and no tmpfs at the socket path.","solutions":["Pre-create the parent directory with writable permissions: `install -d -o <relay-user> -m 0755 /run/buzz` and use BUZZ_UDS_PATH=/run/buzz/relay.sock.","Shorten BUZZ_UDS_PATH to well under 108 bytes total.","If SELinux/AppArmor is involved, allow socket creation in that directory context (or move the socket to a permitted location like /run).","In containers, mount a tmpfs at the socket directory.","Run the relay as a user that owns the socket directory."],"exampleFix":"# before\nexport BUZZ_UDS_PATH=/var/run/buzz/relay/nested/deep/socket.sock\n# error: Failed to bind UDS ...: Permission denied (or path too long)\n\n# after\nsudo install -d -o $USER -m 0755 /run/buzz\nexport BUZZ_UDS_PATH=/run/buzz/relay.sock","handlingStrategy":"validation","validationCode":"p=\"$BUZZ_UDS_PATH\"\ndir=$(dirname \"$p\")\n[ -d \"$dir\" ] && [ -w \"$dir\" ] || { echo \"socket dir $dir missing or not writable\" >&2; exit 1; }\n[ \"${#p}\" -lt 100 ] || { echo \"UDS path too long (kernel sun_path limit ~108)\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep BUZZ_UDS_PATH short (/run/buzz.sock, not deep nested paths).","Create and chown the socket directory in deployment (install -d -o <user> /run/buzz) rather than relying on defaults.","On SELinux hosts, verify the context allows socket creation in the chosen directory.","In containers, mount a tmpfs at the socket directory so the relay can create sockets."],"tags":["rust","unix","uds","unix-socket","permissions","filesystem","startup"],"backgroundTag":"unix-socket-bind-failed","analyzedSha":"ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be","analyzedAt":"2026-08-20T04:38:24.874Z","contentChangedAt":"2026-08-20T04:38:24.874Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}