astrid-runtime/astrid · error

mountpoint is already mounted: {}

Error message

mountpoint is already mounted: {}

What it means

ensure_mountpoint_available finds a registry record for the mountpoint, confirms the kernel lease is live and metadata matches, then probes the running FUSE service via a Status control request. If the service answers with matching access, the mountpoint is genuinely mounted and serving — remounting would fail — so the provider bails telling the user the mountpoint is already mounted.

Source

Thrown at crates/astrid-storage-provider-fuse/src/main.rs:820

        .to_owned();
    let registry: BTreeMap<String, registry::MountRecord> = registry::load_registry()?;
    let Some(record) = registry.get(&key).cloned() else {
        return Ok(());
    };
    let status = kernel_lease_status(client, &record.mount_id).await?;
    let Some(status) = status else {
        cleanup_stale_record(client, acting_principal, &record).await?;
        return Ok(());
    };
    validate_record(&record, &status)?;
    match call_control(
        &record.control_path,
        &ControlRequest::Status {
            requested_by: record.requested_by.clone(),
        },
    ) {
        Ok(ControlResponse::Status { access }) if access == status.access => {
            bail!("mountpoint is already mounted: {}", mountpoint.display())
        },
        Ok(ControlResponse::Status { access }) => {
            bail!("registered FUSE service access {access:?} does not match its lease")
        },
        Ok(_) => bail!("registered FUSE service returned an incompatible status response"),
        Err(_) => {
            cleanup_stale_record(client, acting_principal, &record).await?;
            Ok(())
        },
    }
}

async fn cleanup_stale_record(
    client: &mut AdminClient,
    acting_principal: &astrid_core::PrincipalId,
    record: &registry::MountRecord,
) -> Result<()> {
    let lease_is_live = kernel_lease_status(client, &record.mount_id)

View on GitHub (pinned to affd8760f4)

Solutions

  1. Treat it as success if the mount already matches your intent: check status first and skip mounting if active
  2. Unmount the existing mount first (provider unmount command or fusermount -u) then remount if a fresh mount is required
  3. Serialize mount operations (locks/script guards) so concurrent runs don't race on the same mountpoint
  4. If the existing mount is unwanted/stale, unmount it with the requesting principal so the registry record is cleaned

Example fix

// before: blind remount
mount(client, &principal, mountpoint).await?;
// after: idempotent check
if control_status_says_mounted(mountpoint) {
    eprintln!("{} already mounted, skipping", mountpoint.display());
} else {
    mount(client, &principal, mountpoint).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

// Probe before mounting: is the mountpoint already served?
if let Ok(Some(record)) = registry::record_for_mountpoint(mountpoint) {
    if let Ok(ControlResponse::Status { .. }) = call_control(&record.control_path, &ControlRequest::Status { requested_by: record.requested_by.clone() }) {
        eprintln!("{} already mounted; skipping", mountpoint.display());
        return Ok(());
    }
}

Type guard

fn mountpoint_in_use(mountpoint: &Path) -> bool {
    // /proc/mounts or findmnt check for an active FUSE mount at this path
    std::fs::read_to_string("/proc/mounts")
        .map(|m| m.lines().any(|l| l.split_whitespace().nth(1) == Some(&mountpoint.to_string_lossy())))
        .unwrap_or(false)
}

Try / catch

match mount(client, &principal, mountpoint).await {
    Err(e) if e.to_string().contains("mountpoint is already mounted") => {
        // idempotent success: the mount already exists with the same access
        Ok(())
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling the mount operation for a mountpoint that already has a live lease and a healthy FUSE service answering ControlRequest::Status with access equal to the lease's access. Happens on duplicate mount commands, re-running a script, or two processes mounting the same path concurrently.

Common situations: CI or shell scripts that run 'mount' without checking current state; a teammate's/dev's earlier mount still active; automation retrying after a timeout though the first attempt actually succeeded.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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