clockworklabs/SpacetimeDB · error · io::Error

failed to open file {} for fsync: {}

Error message

failed to open file {} for fsync: {}

What it means

The file variant of the snapshot durability sync: opening the just-written snapshot file with read+write options (write access is required for sync_all to work on Windows) failed. The file vanished between being written and being synced, or permissions/read-only mounts block opening it for write.

Source

Thrown at crates/snapshot/src/lib.rs:1599

                    io::Error::new(
                        e.kind(),
                        format!("failed to open directory {} for fsync: {}", path.display(), e),
                    )
                })?
                .sync_all()
                .map_err(|e| io::Error::new(e.kind(), format!("failed to fsync directory {}: {}", path.display(), e))),
            Self::File(path) => {
                File::options()
                    .read(true)
                    // Windows needs the file to be writable for `sync_all` to work.
                    // Set all the open options explicitly, just for visibility.
                    .write(true)
                    .truncate(false)
                    .create(false)
                    .append(false)
                    .open(path)
                    .map_err(|e| {
                        io::Error::new(
                            e.kind(),
                            format!("failed to open file {} for fsync: {}", path.display(), e),
                        )
                    })?
                    .sync_all()
                    .map_err(|e| io::Error::new(e.kind(), format!("failed to fsync file {}: {}", path.display(), e)))
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::fs::OpenOptions;

    use tempfile::tempdir;

    use super::*;

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Exclude snapshot directories from antivirus/backup interference.
  2. Ensure the snapshot volume is writable and not mounted read-only.
  3. Eliminate processes that concurrently delete snapshot files.
Defensive patterns

Strategy: validation

Validate before calling

use std::fs;

fn snapshot_file_syncable(path: &str) -> bool {
    fs::OpenOptions::new().read(true).write(true).open(path).is_ok()
}

Try / catch

match sync_result {
    Err(e) if e.to_string().contains("failed to open file") => {
        // File vanished between write and sync (AV/backup/cleanup) or the mount is
        // read-only: remove interference, then re-run the snapshot.
    }
    r => r,
}

Prevention

When it happens

Trigger: The snapshot file deleted or moved by another process between write and sync; a read-only filesystem or container bind mount; permission mismatch on the file or directory.

Common situations: Antivirus or backup agents locking/removing fresh files; concurrent snapshot cleanup; read-only bind mounts in containers.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/861dd70a18f24e70. Report an issue: GitHub.