vercel/turborepo · error · std::io::Error
owner-only security descriptor did not contain a DACL
Error message
owner-only security descriptor did not contain a DACL
What it means
set_owner_only_dacl in endpoint.rs builds an owner-only DACL, applies it with SetNamedSecurityInfoW (DACL + PROTECTED_DACL), then reads the descriptor back with GetSecurityDescriptorDacl; this InvalidData error fires when the descriptor comes back with no DACL at all (dacl_present == 0 or null pointer). The ACL write did not stick, so the daemon aborts rather than run with unknown permissions.
Source
Thrown at crates/turborepo-daemon/src/endpoint.rs:287
}
let descriptor = LocalAllocGuard(descriptor as HLOCAL);
let mut dacl_present = 0;
let mut dacl_defaulted = 0;
let mut dacl: *mut ACL = ptr::null_mut();
if unsafe {
GetSecurityDescriptorDacl(
descriptor.0 as PSECURITY_DESCRIPTOR,
&mut dacl_present,
&mut dacl,
&mut dacl_defaulted,
)
} == 0
{
return Err(std::io::Error::last_os_error());
}
if dacl_present == 0 || dacl.is_null() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"owner-only security descriptor did not contain a DACL",
));
}
let path = wide_null(path.as_std_path().as_os_str());
let result = unsafe {
SetNamedSecurityInfoW(
path.as_ptr(),
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
ptr::null_mut(),
ptr::null_mut(),
dacl,
ptr::null_mut(),
)
};
if result == ERROR_SUCCESS {View on GitHub (pinned to f9245100cf)
Solutions
- Point TEMP/TMP and any daemon path override at a local NTFS volume and restart the daemon
- Delete the daemon directory so it is recreated with fresh security descriptors
- If it persists on NTFS, report with the volume type and the path involved
Example fix
# cmd: move temp to a local NTFS drive setx TEMP C:\Users\you\AppData\Local\Temp setx TMP C:\Users\you\AppData\Local\Temp
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure temp/daemon paths live on NTFS before daemon start fs::metadata(&tmp)?.filesystem_type_is_ntfs() // pseudo; check via GetVolumeInformationW
Try / catch
match secure_daemon_dir(path) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains("DACL") => {
// move to a local NTFS path, then retry daemon start
}
other => other?,
} Prevention
- Do not point TEMP/TMP or daemon paths at FAT/network volumes
- Delete and recreate the daemon dir after volume-type changes
When it happens
Trigger: Daemon startup hardening on a volume/path that silently drops or ignores DACL protection — e.g. temp redirected to a FAT-formatted or network drive, or the descriptor being rewritten concurrently.
Common situations: TMP/TEMP overridden to a non-NTFS location (FAT USB stick, some SMB shares) Object IDs / quota states on the volume that reject PROTECTED_DACL writes
Related errors
- daemon socket path is owned by another user: {path}
- daemon socket path did not have an owner SID
- socket path has no parent: {sock_path}
- invalid SID string from Windows: {e}
- daemon socket parent is owned by another user: {socket_dir}
AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17).
Data as JSON: /api/errors/36a26fd3f6704265.
Report an issue: GitHub.