astrid-runtime/astrid · error
mountpoint must be owned by the current OS user: {}
Error message
mountpoint must be owned by the current OS user: {} What it means
prepare_mountpoint validates the user-supplied FUSE mountpoint directory before mounting. It refuses to proceed if the existing directory is not owned by the current OS user (uid mismatch between symlink_metadata and getuid). This prevents a FUSE mount over a directory controlled by another user, which could leak or capture I/O across privilege boundaries.
Source
Thrown at crates/astrid-storage-provider-fuse/src/mountpoint.rs:43
.join(leaf)
});
if !requested.is_absolute() {
bail!("mountpoint must be absolute");
}
let existed = requested.symlink_metadata().is_ok();
if !existed {
std::fs::create_dir_all(&requested)
.with_context(|| format!("create mountpoint {}", requested.display()))?;
}
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());View on GitHub (pinned to affd8760f4)
Solutions
- chown the mountpoint directory to the user running the FUSE service (chown $(id -u) <path>)
- Remove the directory so prepare_mountpoint recreates it with correct ownership
- Run the service as the user who owns the directory
- Verify with stat -c '%u' <path> that the uid matches the running process
Example fix
// before sudo mkdir /mnt/myfuse # owned by root // after sudo mkdir /mnt/myfuse && sudo chown $(id -u):$(id -g) /mnt/myfuse
Defensive patterns
Strategy: validation
Validate before calling
use nix::unistd::getuid;
fn mountpoint_owned_by_current_user(path: &std::path::Path) -> std::io::Result<bool> {
let md = std::fs::symlink_metadata(path)?;
Ok(md.is_dir() && md.uid() == u32::from(getuid()))
} Type guard
fn is_owned_by_current_user(md: &std::fs::Metadata) -> bool {
md.is_dir() && md.uid() == u32::from(nix::unistd::getuid())
} Try / catch
match prepare_mountpoint(&path) {
Err(e) if e.to_string().contains("owned by the current OS user") => {
eprintln!("fix ownership: chown {} $(id -u)", path.display());
}
Err(e) => return Err(e),
Ok(mount) => mount,
} Prevention
- Let prepare_mountpoint create the mountpoint itself instead of pre-creating it
- Never chown the mountpoint to root or another user after creation
- Check `stat -c '%U' <path>` matches the user running the service before mounting
- In systemd units, set User= to the owner of the mountpoint directory
When it happens
Trigger: Calling prepare_mountpoint with a path to a pre-existing directory owned by another uid (e.g. root-created directory, another user's home dir, or a directory whose ownership changed after creation).
Common situations: Running the service under systemd or a container as a different user than the one that created the mountpoint directory; an admin pre-creating /mnt/myfuse as root; chown'ing the mountpoint by mistake.
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
- mount was issued to another acting principal
- mountpoint must be owner-private: {}
- private directory is not owned by the current user: {}
- legacy source entry is not owned by the current user: {}
- capsules are installed, but granting capsule access failed:
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/161f1d23e9689efd.
Report an issue: GitHub.