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.
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
- legacy source entry is not owned by the current user
- private path is not a regular file
- layout migration source contains a special file
- legacy source entry is group/world writable
- mountpoint must be owned by the current OS user
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/2c8cb162e5f3235a.
Report an issue: GitHub.
Appendix: 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)