astrid-runtime/astrid · error

private Windows path has a null DACL: {description}

Error message

private Windows path has a null DACL: {description}

What it means

When validating that a private Windows path (created by this library with a protected DACL limited to the current user, LOCAL_SYSTEM, and Administrators) is actually secure, the library queries the path's security descriptor via GetNamedSecurityInfoW. A null DACL means the object grants everyone full access, so the library refuses it with io::ErrorKind::PermissionDenied rather than continue with an insecure path.

Source

Thrown at crates/astrid-core/src/platform_fs/windows/acl.rs:442

    let status = unsafe {
        GetNamedSecurityInfoW(
            wide.as_ptr(),
            SE_FILE_OBJECT,
            OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
            &raw mut owner,
            null_mut(),
            &raw mut dacl,
            null_mut(),
            &raw mut descriptor,
        )
    };
    if status != ERROR_SUCCESS {
        return Err(io::Error::from_raw_os_error(status.cast_signed()));
    }
    let allocation = LocalAllocation(descriptor);
    let description = path.display().to_string();
    let result = if dacl.is_null() {
        Err(io::Error::new(
            io::ErrorKind::PermissionDenied,
            format!("private Windows path has a null DACL: {description}"),
        ))
    } else {
        // SAFETY: GetNamedSecurityInfoW returned `dacl` inside the descriptor
        // allocation retained by `allocation`.
        unsafe { ValidatedAcl::from_raw(dacl, &allocation, &description) }.and_then(|acl| {
            validate_private_acl_parts(
                &required,
                owner,
                &acl,
                descriptor,
                is_directory,
                &description,
            )
        })
    };
    drop(allocation);

View on GitHub (pinned to affd8760f4)

Solutions

  1. Delete the affected private directory and let the library recreate it, so it gets a correct protected DACL.
  2. Restore the intended ACL manually, e.g. `icacls <path> /inheritance:r /grant:r "%USERNAME%":F` plus SYSTEM/Administrators as needed.
  3. Check what process modified the ACL (Event Viewer / audit policy) and stop it from touching private directories.
  4. Ensure you pass a path that the library created, not a pre-existing user-writable folder.

Example fix

// before: reusing a pre-existing directory with a wiped DACL
let dir = std::path::Path::new("C:\\app\\tmp");
private_temp(dir)?;

// after: let the library create its own private directory
let dir = private_temp(std::env::temp_dir())?;
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the DACL before handing a path to the library (PowerShell):
// $acl = Get-Acl C:\app\tmp
// if (-not $acl.AreAccessRulesProtected) { Remove-Item -Recurse C:\app\tmp }
// if ($acl.Access.Count -eq 0) { Remove-Item -Recurse C:\app\tmp }

Prevention

When it happens

Trigger: Calling private_temp (or anything that calls validate_private_acl) on a Windows path whose security descriptor has no DACL — e.g. the path was created outside the library, or its DACL was removed/replaced after creation.

Common situations: An external tool or script (icacls reset, backup/restore tools, security policy) rewrote the ACL of the private temp directory; mixing library-created private dirs with third-party file managers; restoring files from a backup that dropped the DACL.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/e9ee55d73874a4b1. Report an issue: GitHub.