# How to Debug FUSE Mount Issues in Computerd Using the Real-FUSE Approach

> Debug FUSE mount issues in computerd with the real-FUSE approach. Enable debugging, run in Docker, and verify with the /__computerd/info endpoint.

- Repository: [Cloudflare/computer](https://github.com/cloudflare/computer)
- Tags: how-to-guide
- Published: 2026-08-07

---

**Enable real-FUSE debugging in `computerd` by setting `FUSE_MOUNT=fuse`, running the daemon inside a privileged Docker container with the host's `/dev/fuse` device mounted, and verifying the backend via the `/__computerd/info` HTTP endpoint.**

`computerd` is the Cloudflare Computer daemon that exposes a DO-side **virtual file system (VFS)** to containers through a FUSE mount. While the daemon defaults to auto-detecting the best FUSE backend, subtle bugs—permission errors, stale attributes, and write-buffer flush failures—only manifest with the **kernel FUSE driver**. This guide covers the complete real-FUSE debugging workflow as implemented in [`cloudflare/computer`](https://github.com/cloudflare/computer).

## Why Real-FUSE Debugging Matters

By default, `computerd` probes for FUSE availability and falls back to a userspace shim when `/dev/fuse` is unavailable. The shim masks kernel-specific behavior, so production issues like **EPERM on mount**, **attribute caching bugs**, or **delayed write propagation** require testing against the actual kernel driver.

The real-FUSE approach forces `computerd` to use the native driver and exposes full kernel logging for diagnosis.

## Step 1: Force the Kernel FUSE Driver

Set `FUSE_MOUNT` to bypass auto-detection and require the real backend:

| Platform | Environment Variable |
|----------|---------------------|
| Linux | `FUSE_MOUNT=fuse` |
| macOS | `FUSE_MOUNT=macfuse` |

This configuration is documented in [[`packages/computerd/README.md`](https://github.com/cloudflare/computer/blob/main/packages/computerd/README.md)](packages/computerd/README.md), which describes the `FUSE_MOUNT` values and their fallback behavior.

## Step 2: Configure a Privileged Container

The daemon needs **elevated capabilities** to perform kernel FUSE mounts. The test harness in [[`packages/computerd/src/exec/runner.fuse.test.ts`](https://github.com/cloudflare/computer/blob/main/packages/computerd/src/exec/runner.fuse.test.ts)](packages/computerd/src/exec/runner.fuse.test.ts) demonstrates the required Docker flags:

```bash
docker run --rm -it \
  --privileged \
  -v /dev/fuse:/dev/fuse \
  -e FUSE_MOUNT=fuse \
  -e MOUNT_POINT=/workspace \
  -e PORT=45678 \
  cloudflare/computerd:latest \
  sh -c "npm exec --workspace @cloudflare/computerd -- bin/computerd"

```

Critical flags explained:

- `--privileged` — Grants `CAP_SYS_ADMIN` and other capabilities required for `mount(2)` syscalls
- `-v /dev/fuse:/dev/fuse` — Exposes the host's FUSE device node to the container
- `FUSE_MOUNT=fuse` — Forces kernel driver selection instead of the shim fallback

## Step 3: Verify Real-FUSE Activation

Once running, confirm the backend via the injected service endpoint documented in [[`docs/07_injected_service.md`](https://github.com/cloudflare/computer/blob/main/docs/07_injected_service.md)](docs/07_injected_service.md):

```bash
curl http://localhost:45678/__computerd/info | jq .

```

The response should contain `"fuse"` in the `backend` field. If it shows `"shim"` or `"nodefs"`, the kernel driver failed to initialize—check that `/dev/fuse` exists inside the container and that `--privileged` was applied.

## Step 4: Exercise the FUSE Mount

Trigger filesystem operations through `computerd`'s RPC APIs to stress-test the mount. The real-FUSE test case in [[`packages/computerd/src/cli/computerd.test.ts`](https://github.com/cloudflare/computer/blob/main/packages/computerd/src/cli/computerd.test.ts)](packages/computerd/src/cli/computerd.test.ts) validates this flow:

```bash

# Write through the exec API

curl -X POST http://localhost:45678/exec \
  -H "Content-Type: application/json" \
  -d '{"cmd":["/bin/bash","-c","echo hello > /workspace/hello.txt"]}'

# Read back via the mount directly

cat /workspace/hello.txt

```

Operations that create, modify, or stat files will generate FUSE requests visible in kernel logs.

## Step 5: Capture Kernel-Level Diagnostics

Enable verbose FUSE tracing to observe the request-response cycle:

```bash

# Add debug logging to the container launch

-e FUSE_DEBUG=1

```

Logs appear on `stderr` and can be retrieved with `docker logs`. For deeper analysis, inspect kernel messages inside the privileged container:

```bash
dmesg | grep -i fuse

```

The skill file at [[`.agents/skills/debugging-computerd-fuse/SKILL.md`](https://github.com/cloudflare/computer/blob/main/.agents/skills/debugging-computerd-fuse/SKILL.md)](.agents/skills/debugging-computerd-fuse/SKILL.md) provides structured guidance on log collection and interpretation.

## Step 6: Diagnose Common Failure Modes

| Symptom | Root Cause | Fix |
|---------|-----------|-----|
| Falls back to shim (`backend: "nodefs"`) | `/dev/fuse` missing in container | Verify `-v /dev/fuse:/dev/fuse` and host driver installation |
| `EPERM` on mount syscall | Missing `CAP_SYS_ADMIN` | Add `--privileged` or explicit `--cap-add SYS_ADMIN` |
| Stale file attributes | Kernel attribute caching | Set `COMPUTERD_FUSE_AUTO_CACHE=0` to disable caching |
| Write buffering delays | FUSE writeback cache | Force synchronous writes or reduce buffer sizes |

The guard in [[`packages/computerd/README.md`](https://github.com/cloudflare/computer/blob/main/packages/computerd/README.md)](packages/computerd/README.md) automatically skips real-FUSE tests when `/dev/fuse` is absent, preventing false failures.

## Step 7: Iterate and Validate Changes

After modifying environment variables or source code:

1. Rebuild the workspace: `npm run build`
2. Restart the privileged container with updated flags
3. Verify RPC contract compliance per [[`docs/08_capnweb_interface.md`](https://github.com/cloudflare/computer/blob/main/docs/08_capnweb_interface.md)](docs/08_capnweb_interface.md)
4. Re-run the test suite to confirm FUSE behavior stability

## Summary

- **Force kernel FUSE** with `FUSE_MOUNT=fuse` (Linux) or `macfuse` (macOS)
- **Run privileged** with `--privileged` and host `/dev/fuse` mounted
- **Verify activation** via `GET /__computerd/info` endpoint
- **Enable tracing** with `FUSE_DEBUG=1` and inspect `dmesg` for kernel errors
- **Address common issues**: missing device node, capability errors, and attribute caching
- **Maintain RPC stability** when iterating on FUSE-related changes

## Frequently Asked Questions

### What does `FUSE_MOUNT=auto` do and why avoid it for debugging?

The `auto` setting probes `/dev/fuse` and macFUSE availability, then falls back to the userspace shim if neither is accessible. For debugging production FUSE issues, `auto` masks the very behavior you need to reproduce. Always set `FUSE_MOUNT=fuse` or `macfuse` explicitly to guarantee kernel driver usage.

### Why is `--privileged` required instead of just `--cap-add SYS_ADMIN`?

While `--cap-add SYS_ADMIN` grants the mount capability, the kernel FUSE driver also requires access to the device node permissions and may need additional capabilities for security module interactions. The test harness in [`runner.fuse.test.ts`](https://github.com/cloudflare/computer/blob/main/runner.fuse.test.ts) uses `--privileged` as the reliable baseline;最小化特权化可作为后续优化探索。

### How do I confirm writes actually propagated through FUSE rather than cached locally?

Write through the `computerd` HTTP API (`/exec` or `/pull`), then read the same path directly from the mount point with standard filesystem tools like `cat` or `stat`. If the content differs, the VFS write buffer has not flushed—check `COMPUTERD_FUSE_AUTO_CACHE` settings and FUSE debug logs for flush operations.