{"record":{"id":"773f6f9bf76bd3b8","repo":"vercel/turborepo","slug":"daemon-socket-parent-is-owned-by-another-user-so","errorCode":null,"errorMessage":"daemon socket parent is owned by another user: {socket_dir}","messagePattern":"daemon socket parent is owned by another user: (.+?)","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/turborepo-daemon/src/endpoint.rs","lineNumber":504,"sourceCode":"\n#[cfg(unix)]\nfn secure_unix_dir(socket_dir: &AbsoluteSystemPath) -> Result<(), std::io::Error> {\n    use std::os::unix::fs::{DirBuilderExt, MetadataExt, PermissionsExt};\n\n    std::fs::DirBuilder::new()\n        .recursive(true)\n        .mode(PRIVATE_DIR_MODE)\n        .create(socket_dir.as_std_path())?;\n\n    let metadata = std::fs::symlink_metadata(socket_dir.as_std_path())?;\n    if !metadata.file_type().is_dir() {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::PermissionDenied,\n            format!(\"daemon socket parent is not a directory: {socket_dir}\"),\n        ));\n    }\n    if metadata.uid() != current_uid() {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::PermissionDenied,\n            format!(\"daemon socket parent is owned by another user: {socket_dir}\"),\n        ));\n    }\n\n    let mode = metadata.permissions().mode() & 0o777;\n    if mode != PRIVATE_DIR_MODE {\n        std::fs::set_permissions(\n            socket_dir.as_std_path(),\n            std::fs::Permissions::from_mode(PRIVATE_DIR_MODE),\n        )?;\n    }\n\n    Ok(())\n}\n\n#[cfg(unix)]\nfn set_private_socket_permissions(sock_path: &AbsoluteSystemPath) -> Result<(), std::io::Error> {","sourceCodeStart":486,"sourceCodeEnd":522,"githubUrl":"https://github.com/vercel/turborepo/blob/f9245100cf0d31d96628804ead485f6bf226e55a/crates/turborepo-daemon/src/endpoint.rs#L486-L522","documentation":"secure_unix_dir (endpoint.rs:504) compares metadata.uid() from symlink_metadata against libc::geteuid(); a mismatch yields this PermissionDenied error. The daemon hardens both the socket dir and its parent, so it refuses when either directory is owned by another uid — otherwise a different user could pre-create or rewrite those directories and hijack the socket.","triggerScenarios":"Daemon start when the socket dir or its parent was created by another uid: previously running turbo under sudo, shared HOME between accounts, containers with mismatched uid maps, or root-created leftovers in /tmp-adjacent paths.","commonSituations":"`sudo turbo ...` once created root-owned ~/.cache/turborepo Shared CI machines where another user's env pointed at the same paths Volume-mounted home dirs with shifted uids","solutions":["Remove the offending directory shown in the message with sufficient privileges (e.g. `sudo rm -rf <path>`) so your uid recreates it","Never mix uids for the same HOME/cache paths; run turbo and daemon as the same user","In containers, keep the runtime dir on a per-uid path (XDG_RUNTIME_DIR) instead of a shared one"],"exampleFix":"# bash: clear root-owned daemon dir, restart as yourself\nsudo rm -rf ~/.cache/turborepo\nturbo daemon restart","handlingStrategy":"fallback","validationCode":"// unix: pre-check ownership of socket dir and its parent\nlet m = std::fs::symlink_metadata(dir)?;\nuse std::os::unix::fs::MetadataExt;\nif m.uid() != unsafe { libc::geteuid() } {\n    anyhow::bail!(\"{dir} owned by uid {}, refusing to start\", m.uid());\n}","typeGuard":null,"tryCatchPattern":"// on ownership mismatch: remove and let the daemon recreate\nErr(e) if e.kind() == std::io::ErrorKind::PermissionDenied\n    && e.to_string().contains(\"owned by another user\") => {\n    // may need elevated removal if root-owned\n    std::process::Command::new(\"sudo\").arg(\"rm\").arg(\"-rf\").arg(dir).status()?;\n    daemon_start()?;\n}","preventionTips":["Never run turbo under sudo against your user HOME/cache paths","Use XDG_RUNTIME_DIR (per-uid) for sockets on multi-user machines"],"tags":["daemon","unix","security","permissions","ownership"],"backgroundTag":"file-ownership-mismatch","analyzedSha":"f9245100cf0d31d96628804ead485f6bf226e55a","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}