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

  1. chmod 700 <mountpoint> before invoking the mount operation
  2. Remove the directory and let prepare_mountpoint create it with 0o700
  3. 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

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


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/3259adb343e88910. Report an issue: GitHub.