vercel/turborepo · error · std::io::Error
daemon socket path is owned by another user: {path}
Error message
daemon socket path is owned by another user: {path} What it means
During Windows daemon startup, ensure_current_user_owns_path (endpoint.rs:241) reads the path's owner SID with GetNamedSecurityInfoW and compares it to the current user's SID with EqualSid. A mismatch produces this PermissionDenied error: the directory that will host the daemon socket belongs to a different account, so turbo refuses to run there to stop another user from controlling the pipe directory.
Source
Thrown at crates/turborepo-daemon/src/endpoint.rs:241
ConvertSidToStringSidW, ConvertStringSecurityDescriptorToSecurityDescriptorW,
GetNamedSecurityInfoW, SetNamedSecurityInfoW, SDDL_REVISION_1, SE_FILE_OBJECT,
},
EqualSid, GetSecurityDescriptorDacl, GetTokenInformation, TokenUser, ACL,
DACL_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION,
PROTECTED_DACL_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, PSID, TOKEN_QUERY,
TOKEN_USER,
},
System::Threading::{GetCurrentProcess, OpenProcessToken},
};
pub fn ensure_current_user_owns_path(path: &AbsoluteSystemPath) -> Result<(), std::io::Error> {
let current_user = current_user_sid()?;
let owner = path_owner_sid(path)?;
if unsafe { EqualSid(current_user.as_ptr(), owner.as_ptr()) } != 0 {
Ok(())
} else {
Err(std::io::Error::new(
std::io::ErrorKind::PermissionDenied,
format!("daemon socket path is owned by another user: {path}"),
))
}
}
pub fn set_owner_only_dacl(
path: &AbsoluteSystemPath,
inherit_to_children: bool,
) -> Result<(), std::io::Error> {
let current_user = current_user_sid()?;
let current_user = sid_to_string(current_user.as_ptr())?;
let inherit_flags = if inherit_to_children { "OICI" } else { "" };
let sddl = format!("D:P(A;{inherit_flags};FA;;;{current_user})");
let sddl = wide_null(OsStr::new(&sddl));
let mut descriptor = ptr::null_mut();
if unsafe {View on GitHub (pinned to f9245100cf)
Solutions
- Delete the stale daemon directory shown in the message (usually under %TEMP%\turborepo or the user profile) so the current user recreates it
- Take ownership of the existing directory: `takeown /f <path> /r` then `icacls <path> /setowner <you>`
- Always run turbo/daemon as the same Windows account that owns those dirs
Example fix
:: stop daemon, remove stale dir, restart turbo daemon stop rmdir /s /q "%TEMP%\turborepo" turbo daemon start
Defensive patterns
Strategy: fallback
Validate before calling
// Windows: check ownership before starting the daemon
fn owned_by_me(path: &Path) -> bool {
// use windows_acl or icacls exit code in a pre-step
std::process::Command::new("icacls").arg(path).status().map(|s| s.success()).unwrap_or(false)
} Try / catch
// on PermissionDenied 'owned by another user': drop the dir and retry once
match start_daemon() {
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied && e.to_string().contains("owned by another user") => {
std::fs::remove_dir_all(daemon_dir).ok();
start_daemon()?; // retry once after recreation
}
r => r,
} Prevention
- Run turbo and its daemon under one Windows account
- After runas/service experiments, clear the daemon dir under %TEMP%
When it happens
Trigger: Daemon start where the socket dir (typically under %TEMP% or the user profile) was created by a different Windows account — admin provisioning, `runas`/service-account runs, or a profile restored from another machine.
Common situations: Machine shared between accounts and turbo daemon dirs created by the first one Running the daemon as a service/scheduled task under SYSTEM after using it interactively Profile migration/cloning keeping old ownership
Related errors
- daemon socket path did not have an owner SID
- daemon socket parent is owned by another user: {socket_dir}
- owner-only security descriptor did not contain a DACL
- invalid SID string from Windows: {e}
- socket path has no parent: {sock_path}
AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17).
Data as JSON: /api/errors/1609a8ee80be0217.
Report an issue: GitHub.