astrid-runtime/astrid · error
private file is not owner-only: {}
Error message
private file is not owner-only: {} What it means
A private file must have mode exactly 0600 (owner read/write, no group/other bits). The library throws this when validation finds st_mode & 0o777 != 0o600, because looser permissions would expose security-sensitive content to other local users.
Source
Thrown at crates/astrid-core/src/platform_fs.rs:557
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()),
));
}
if metadata.st_uid != nix::unistd::getuid().as_raw() {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
format!(
"private file is not owned by the current user: {}",
path.display()
),
));
}
if metadata.st_mode & 0o777 != 0o600 {
return Err(io::Error::new(
io::ErrorKind::PermissionDenied,
format!("private file is not owner-only: {}", path.display()),
));
}
if metadata.st_nlink != 1 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"private file has {} links; durable media must have exactly one",
metadata.st_nlink
),
));
}
validate_no_extended_acl(path)?;
Ok(())
}
#[cfg(target_os = "macos")]View on GitHub (pinned to affd8760f4)
Solutions
- Chmod the file to owner-only: `chmod 600 <path>`.
- Call the library's restrict_private_file, which fchmods the file to 0600 and revalidates.
- Delete and recreate the file through the library so it is created with 0600.
- Ensure any external tooling that rewrites the file also sets 0600 (set umask 077 or explicit chmod in scripts).
Example fix
// before (file has 0644)
validate_private_file(Path::new("/home/me/.astrid/credentials"))?;
// after (fix mode first)
// $ chmod 600 /home/me/.astrid/credentials
validate_private_file(Path::new("/home/me/.astrid/credentials"))?; Defensive patterns
Strategy: validation
Validate before calling
use std::os::unix::fs::PermissionsExt;
fn mode_is_600(path: &std::path::Path) -> bool {
std::fs::metadata(path).map(|m| m.permissions().mode() & 0o777 == 0o600).unwrap_or(false)
} Type guard
fn is_owner_only(path: &std::path::Path) -> bool {
std::fs::metadata(path)
.map(|m| m.permissions().mode() & 0o777 == 0o600)
.unwrap_or(false)
} Try / catch
if let Err(e) = validate_private_file(path) {
if e.kind() == std::io::ErrorKind::PermissionDenied {
std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o600))?;
} else { return Err(e.into()); }
} Prevention
- Run with umask 077 in scripts that touch private files
- chmod 600 after any external tool rewrites the file
- Preserve modes carefully when restoring backups
When it happens
Trigger: validate_private_file sees a file with e.g. 0644, 0664, or 0666 permissions. Happens when the file was created outside the library, copied with permissions preserved, or had permissions loosened after creation.
Common situations: rsync/scp/tar copies preserving 0644; a umask of 0022 applied when another tool created the file; editor or backup tool rewrote the file with default perms; restoring from a backup with relaxed modes.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- legacy source entry is not owned by the current user: {}
- legacy source entry is group/world writable: {}
- capsules are installed, but granting capsule access failed:
- {install_dir} is not writable — re-run with elevated permiss
- mountpoint ancestor is writable without sticky protection: {
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/49806929015d39bb.
Report an issue: GitHub.