astrid-runtime/astrid · error
mountpoint must be owner-private: {}
Error message
mountpoint must be owner-private: {} What it means
prepare_mountpoint requires a pre-existing mountpoint directory to be owner-private: its permission mode must have no group or other bits set (mode & 0o077 == 0). Directories created by the function itself get 0o700; anything looser on a pre-existing dir is rejected to keep the mount contents private to the owner.
Source
Thrown at crates/astrid-storage-provider-fuse/src/mountpoint.rs:52
}
astrid_core::platform_fs::verify_no_redirects(&requested)
.with_context(|| format!("reject redirected mountpoint {}", requested.display()))?;
let metadata = std::fs::symlink_metadata(&requested)?;
if !metadata.is_dir() {
bail!("mountpoint is not a directory: {}", requested.display());
}
let expected_uid = u32::from(getuid());
if metadata.uid() != expected_uid {
bail!(
"mountpoint must be owned by the current OS user: {}",
requested.display()
);
}
let mode = metadata.permissions().mode();
if !existed {
std::fs::set_permissions(&requested, Permissions::from_mode(0o700))?;
} else if mode & 0o077 != 0 {
bail!("mountpoint must be owner-private: {}", requested.display());
}
if std::fs::read_dir(&requested)?.next().is_some() {
bail!("mountpoint is not empty: {}", requested.display());
}
let canonical = requested
.canonicalize()
.with_context(|| format!("canonicalize mountpoint {}", requested.display()))?;
if mountinfo_contains(&canonical)? {
bail!("mountpoint is already mounted: {}", canonical.display());
}
Ok((canonical, !existed))
}
/// Return current owner identity for synthetic inode metadata.
pub(crate) fn owner_ids() -> (u32, u32) {
(getuid().into(), getgid().into())
}
View on GitHub (pinned to affd8760f4)
Solutions
- chmod 700 <mountpoint> before invoking the mount operation
- Remove the directory and let prepare_mountpoint create it with 0o700
- Update provisioning scripts/templates to create the mountpoint with mode 0700
Example fix
// before mkdir -p /mnt/myfuse # mode 755 // after mkdir -p /mnt/myfuse && chmod 700 /mnt/myfuse
Defensive patterns
Strategy: validation
Validate before calling
fn mountpoint_is_owner_private(path: &std::path::Path) -> std::io::Result<bool> {
use std::os::unix::fs::PermissionsExt;
let md = std::fs::symlink_metadata(path)?;
Ok(md.is_dir() && md.permissions().mode() & 0o077 == 0)
} Type guard
fn is_owner_private(md: &std::fs::Metadata) -> bool {
use std::os::unix::fs::PermissionsExt;
md.is_dir() && md.permissions().mode() & 0o077 == 0
} Try / catch
match prepare_mountpoint(&path) {
Err(e) if e.to_string().contains("owner-private") => {
let _ = std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o700));
// retry once
}
other => other?,
} Prevention
- Always chmod 700 pre-existing mountpoint directories
- Create mountpoints with umask 077 or explicitly chmod 700 in provisioning scripts
- Prefer letting the library create the directory (mode 0o700 enforced automatically)
- Audit shared/provisioned mount directories for group/other bits
When it happens
Trigger: Passing an existing directory whose mode includes group/other permission bits (e.g. 0o755, 0o775) to prepare_mountpoint instead of letting the library create the directory.
Common situations: mkdir -p default umask 022 creating 755 directories; a shared mountpoint directory created by a provisioning script with group access.
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
- mountpoint must be owned by the current OS user: {}
- 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: {
- FUSE mount completed but is absent from the Linux mount tabl
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/3259adb343e88910.
Report an issue: GitHub.