Android: newly written note reads back as 0 bytes for minutes to hours, then content reappears (FUSE writeback-cache staleness on /sdcard)

Steps to reproduce

  1. Open a vault located in shared storage on Android (e.g. /storage/emulated/0/Documents/<vault>).
  2. Create notes rapidly while other file activity happens concurrently, e.g. run this in the developer console in two parallel loops (or with a sync plugin active):
    for (let i = 0; i < 40; i++) app.vault.create(`repro/n${i}.md`, 'x'.repeat(60));
    
  3. Check every created file with app.vault.adapter.read(path) and file.stat.size.

Minimal reproduction without Obsidian (adb shell, same device): write a file with echo "<62 bytes>" > f while two other processes run stat f as soon as it exists. About 1–6% of files read back as 0 bytes (0 of 300 without the concurrent stat).

Expected result

Every note contains the written content immediately after vault.create / adapter.write resolves.

Actual result

About 1 in 20–40 notes shows stat.size 0, and adapter.read / cachedRead return an empty string. This lasts from minutes to hours (in one case until Android killed the backgrounded app). Afterwards the file on disk has the correct content, with an mtime a few ms after creation. Sync plugins may upload the empty version in the meantime.

Diagnostic signature from adb shell stat: Size: 0, Blocks: 8, atime = mtime = ctime = creation time. Rewriting the file fixes it immediately; mv / touch do not.

Analysis

The Android write path (Filesystem writeFile → FileOutputStream / BufferedWriter.write / close) is synchronous and correct, and the issue reproduces with plain shell commands, so the root cause is below Obsidian.

MediaProvider’s FUSE daemon enables FUSE_CAP_WRITEBACK_CACHE with infinite attr/entry timeouts. In that mode the kernel ignores the server-reported size/mtime for regular files, so a cached inode that picked up size 0 during the create→write window is never refreshed until it is evicted. Obsidian’s file watcher (CREATE/CLOSE_WRITE → stat) and concurrent writes widen the window. I intend to report the underlying issue to Android as well.

Possible mitigation in Obsidian: verify after write on Android (re-stat or read back, and rewrite on a size mismatch), and avoid publishing a 0-byte stat for a just-written file.

Environment

  • Obsidian Android 1.13.8
  • Samsung Galaxy Z Fold3 (SM-F926B), Android 15 (SDK 35), kernel 5.4
  • Vault in /storage/emulated/0/Documents
  • Reproduces with Obsidian not running at all (shell-only reproduction above), so it does not depend on plugins. Not yet re-tested in the Sandbox vault; I can add the debug info block on request.

Thank you for report. We had a couple of similar reports in the past but I am not 100% sure it’s the same problem yet. We will investigate it.

If you open a BR to Android, please share the link here.

Thanks again