benbjohnson/litestream · error
init write buffer: %w
Error message
init write buffer: %w
What it means
On a cold enable, SetWriteEnabledWithTimeout(true) tried to create/open the write-buffer file via initWriteBufferWithLock and failed. The write buffer is the local durable file holding dirty pages between SQLite writes and remote LTX syncs, so writes cannot be enabled without it.
Source
Thrown at vfs.go:1934
} else if f.vfs != nil {
// Use VFS temp directory
dir, err := f.vfs.ensureTempDir()
if err != nil {
f.mu.Unlock()
return fmt.Errorf("create temp dir for write buffer: %w", err)
}
f.bufferPath = filepath.Join(dir, "write-buffer")
} else {
// Fallback to os.TempDir() for cold enable without VFS reference
f.bufferPath = filepath.Join(os.TempDir(), "litestream-write-buffer")
}
}
// Initialize buffer file if not present
if f.bufferFile == nil {
if err := f.initWriteBufferWithLock(); err != nil {
f.mu.Unlock()
return fmt.Errorf("init write buffer: %w", err)
}
}
// Initialize write tracking state if this is a cold enable
if f.pendingTXID == 0 {
f.expectedTXID = f.pos.TXID
f.pendingTXID = f.pos.TXID + 1
}
// Start sync ticker if not running and interval > 0
// (syncInterval == 0 means no periodic sync, only manual Sync() calls)
if f.syncTicker == nil && f.syncInterval > 0 {
f.syncTicker = time.NewTicker(f.syncInterval)
f.syncStop = make(chan struct{})
stopCh := f.syncStop
tickerCh := f.syncTicker.C
f.wg.Add(1)
go func() { defer f.wg.Done(); f.syncLoop(stopCh, tickerCh) }()View on GitHub (pinned to 4ed7a308f6)
Solutions
- Create the buffer directory and grant write permission: mkdir -p <bufferPath dir> && chown appuser it.
- Set WriteBufferPath to a verified-writable volume and ensure the directory exists before enabling.
- Check the wrapped error for the exact open/create failure (EACCES, ENOSPC, EISDIR) and fix accordingly.
- Free disk space on the buffer volume if the error is ENOSPC.
- Remove stale litestream-write-buffer files from a previous crashed run if ownership/locks conflict.
Example fix
// before
vfs.WriteBufferPath = "/data/litestream" // dir does not exist
// after
os.MkdirAll("/data/litestream", 0o755)
vfs.WriteBufferPath = "/data/litestream/write-buffer.bin" Defensive patterns
Strategy: validation
Validate before calling
// Go: validate buffer path before SetWriteEnabled(true)
func validateBufferPath(p string) error {
dir := filepath.Dir(p)
if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
return fmt.Errorf("buffer dir %s unusable: %w", dir, err)
}
f, err := os.OpenFile(p, os.O_CREATE|os.O_RDWR, 0o644)
if err != nil { return err }
return f.Close()
} Try / catch
if err := file.SetWriteEnabled(true); err != nil {
if strings.HasPrefix(err.Error(), "init write buffer:") {
// inspect wrapped *fs.PathError: EACCES/ENOSPC/EISDIR and fix path
}
} Prevention
- Create the buffer directory (MkdirAll) before enabling writes.
- Keep the buffer on a volume with free space; alert on ENOSPC.
- Remove stale buffer files from crashed previous runs.
- Exclude the buffer file from external cleanup jobs.
When it happens
Trigger: SetWriteEnabled(true) when f.bufferFile == nil and the buffer path is unusable: parent directory doesn't exist, permission denied creating the file, disk full, or path exists as a directory. The bufferPath may come from WriteBufferPath, ensureTempDir, or os.TempDir().
Common situations: WriteBufferPath pointing to a missing directory (no MkdirAll beforehand); read-only container filesystem; another process holds conflicting permissions on the buffer file; disk full on the volume hosting the buffer; stale buffer file left by a crashed prior process with wrong ownership.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- write to buffer: %w
- read page %d from buffer for cache: %w
- create buffer directory: %w
- page size mismatch: got %d, expected %d
- context cancelled while waiting for transaction: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/ebe00d401d3ea249.
Report an issue: GitHub.