astrid-runtime/astrid · error

private directory is not owner-only: {}

Error message

private directory is not owner-only: {}

What it means

validate_private_directory_unix requires the directory's permission mode to be exactly 0700 (owner read/write/execute, nothing for group or other). Any looser mode (e.g. 0755 or 0770) widens access beyond the owner and fails with io::ErrorKind::PermissionDenied. Extended ACLs are checked separately afterwards.

Source

Thrown at crates/astrid-core/src/platform_fs.rs:506

}

#[cfg(unix)]
fn validate_private_directory_unix(path: &Path) -> io::Result<()> {
    use std::os::unix::fs::{MetadataExt as _, PermissionsExt as _};

    let directory = open_directory_no_follow_unix(path)?;
    let metadata = directory.metadata()?;
    if metadata.uid() != nix::unistd::getuid().as_raw() {
        return Err(io::Error::new(
            io::ErrorKind::PermissionDenied,
            format!(
                "private directory is not owned by the current user: {}",
                path.display()
            ),
        ));
    }
    if metadata.permissions().mode() & 0o777 != 0o700 {
        return Err(io::Error::new(
            io::ErrorKind::PermissionDenied,
            format!("private directory is not owner-only: {}", path.display()),
        ));
    }
    validate_no_extended_acl(path)?;
    Ok(())
}

#[cfg(unix)]
fn restrict_private_file_unix(path: &Path) -> io::Result<()> {
    use nix::sys::stat::{Mode, fchmod, fstat};

    let file = open_file_no_follow_unix(path)?;
    let metadata = fstat(&file).map_err(nix_io_error)?;
    if metadata.st_mode & 0o170_000 != 0o100_000 {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!("private path is not a regular file: {}", path.display()),

View on GitHub (pinned to affd8760f4)

Solutions

  1. chmod 700 the directory (and any nested real directories), or call ensure_private_directory / ensure_private_directory_tree which repairs modes automatically.
  2. Remove the permissive directory and let the library recreate it with 0700.
  3. Check for tools (backups, sync clients) that rewrite permissions and re-run validation after they run.

Example fix

// before (shell)
ls -ld ~/.astrid  // drwxr-xr-x
// after (shell)
chmod 700 ~/.astrid
// or in Rust: let the library repair it
ensure_private_directory_tree(&home.join(".astrid"))?;
Defensive patterns

Strategy: validation

Validate before calling

#[cfg(unix)]
fn is_owner_only(p: &std::path::Path) -> std::io::Result<bool> {
    use std::os::unix::fs::PermissionsExt;
    Ok(std::fs::metadata(p)?.permissions().mode() & 0o777 == 0o700)
}

Type guard

#[cfg(unix)]
fn has_0700(p: &std::path::Path) -> bool {
    use std::os::unix::fs::PermissionsExt;
    std::fs::metadata(p)
        .map(|m| m.permissions().mode() & 0o777 == 0o700)
        .unwrap_or(false)
}

Try / catch

match validate_private_directory(&dir) {
    Err(e) if e.kind() == io::ErrorKind::PermissionDenied && e.to_string().contains("owner-only") => {
        #[cfg(unix)]
        {
            use std::os::unix::fs::PermissionsExt;
            std::fs::set_permissions(&dir, std::fs::Permissions::from_mode(0o700))?;
        }
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling validate_private_directory or ensure_private_directory_unix on an existing directory whose mode & 0o777 != 0o700 — typically a 0755 layout-1 leftover or a umask-loosened mkdir.

Common situations: Older Astrid layouts (0755 COW slots/unpacked homes) after upgrade; restores that lost the 0700 bit; processes with permissive umask creating the directory first.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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