astrid-runtime/astrid · error
private file is not owned by the current user: {}
Error message
private file is not owned by the current user: {} What it means
Private files must be owned by the current user; the library compares the inode's st_uid to getuid() during validation. If the file exists but belongs to another uid, it refuses to treat it as private, preventing use of state another account could manipulate.
Source
Thrown at crates/astrid-core/src/platform_fs.rs:548
#[cfg(target_os = "macos")]
remove_extended_acl_macos(path)?;
validate_private_file_unix(path)
}
#[cfg(unix)]
fn validate_private_file_unix(path: &Path) -> io::Result<()> {
use nix::sys::stat::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()),
));
}
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",View on GitHub (pinned to affd8760f4)
Solutions
- Chown the file to the current user: `sudo chown $(id -u):$(id -g) <path>`.
- Fix the directory ownership recursively: `sudo chown -R $(id -u) <dir>`.
- Delete the file and let the library recreate it as the current user (atomic_write_private_file).
- Run the application as the user who owns the file, or stop using sudo for it.
Example fix
// before (file owned by root)
validate_private_file(Path::new("/home/me/.astrid/credentials"))?;
// after (fix ownership first)
// $ sudo chown $(id -u):$(id -g) /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::MetadataExt;
fn owned_by_me(path: &std::path::Path) -> bool {
std::fs::metadata(path).map(|m| m.uid() == unsafe { libc::getuid() }).unwrap_or(false)
} Type guard
fn is_self_owned(path: &std::path::Path) -> bool {
std::fs::metadata(path).map(|m| m.uid() == nix::unistd::getuid().as_raw()).unwrap_or(false)
} Try / catch
match validate_private_file(path) {
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
println!("fix ownership: sudo chown $(id -u) {path:?}");
},
other => other?,
} Prevention
- Never create private state with sudo
- Use `rsync -o`/preserve ownership when migrating home directories
- In containers, match the runtime uid to the volume's file owner
When it happens
Trigger: validate_private_file (or restrict_private_file, which validates at the end) encounters a file whose st_uid differs from the current uid — e.g. created by root, another user, or after a uid change.
Common situations: Files created by running the tool with sudo; a shared/home-directory migration where ownership was not preserved (rsync without -o, tar as another user); container running as a different uid than the volume's file owner; uid remap after LDAP/NSS change.
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
- private path is not a regular file: {}
- legacy source entry is not owned by the current user: {}
- mountpoint must be owned by the current OS user: {}
- layout migration source contains a special file: {}
- private directory is not owned by the current user: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/2c8cb162e5f3235a.
Report an issue: GitHub.