benbjohnson/litestream · error

initialize write buffer

Error message

initialize write buffer: %w

What it means

Raised during VFSFile.Open when write support is enabled and initializing the durable write buffer file fails. The write buffer is a local file that accumulates pending pages for durability before they are replicated; if it cannot be created/opened, the database cannot be opened in writable mode.

Solutions

  1. Check that the write buffer path exists, is writable, and has free space (df, ls -l)
  2. Ensure no other litestream/VFS process holds the buffer file open
  3. Fix filesystem mounts (make read-only mounts writable or relocate the buffer path)
  4. Disable write mode if only reads are needed (don't enable writes on this file)

Example fix

// before
vfs.NewVFS(..., CacheSize, WriteBufferDir: "/ro-mount/buf")
// after
// ensure dir is writable before enabling writes
os.MkdirAll(bufDir, 0o755); checkWritable(bufDir)
vfs.NewVFS(..., WriteBufferDir: bufDir)
Defensive patterns

Strategy: validation

Validate before calling

if err := os.MkdirAll(bufDir, 0o755); err != nil { return err }
if err := checkWritable(bufDir); err != nil { return err } // test-create+remove a temp file

Type guard

func dirWritable(dir string) bool { f, err := os.CreateTemp(dir, "t"); if err != nil { return false }; f.Close(); os.Remove(f.Name()); return true }

Try / catch

if err := file.Open(ctx); err != nil {
    var we *fs.PathError
    if errors.As(err, &we) && strings.Contains(err.Error(), "initialize write buffer") {
        logger.Error("write buffer unusable; open in read-only mode instead", "error", err)
    }
    return err
}

Prevention

When it happens

Trigger: initWriteBuffer fails because the buffer directory does not exist or is not writable, the disk is full, an OS open/create error occurs, or the existing buffer file is locked/corrupt and cannot be discarded.

Common situations: Buffer path on a read-only or full filesystem; wrong buffer directory permissions; leftover buffer file held by another process; container with a read-only root filesystem.

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/a0cdfd05ef1d0837. Report an issue: GitHub.

Appendix: source

Thrown at vfs.go:1153

	}
	f.cache = cache

	// Determine the current position based off the latest LTX file.
	var pos ltx.Pos
	if len(infos) > 0 {
		pos = ltx.Pos{TXID: infos[len(infos)-1].MaxTXID}
	}
	f.pos = pos

	// Initialize write support TXID tracking
	if f.writeEnabled {
		f.expectedTXID = pos.TXID
		f.pendingTXID = pos.TXID + 1
		f.logger.Debug("write support enabled", "expectedTXID", f.expectedTXID, "pendingTXID", f.pendingTXID)

		// Initialize write buffer file for durability (discards any existing buffer)
		if err := f.initWriteBuffer(); err != nil {
			return fmt.Errorf("initialize write buffer: %w", err)
		}
	}

	// Build the page index so we can lookup individual pages.
	if err := f.buildIndex(f.ctx, infos); err != nil {
		f.logger.Error("cannot build index", "error", err)
		return fmt.Errorf("cannot build index: %w", err)
	}

	// Start background hydration if enabled
	if f.hydrationPath != "" {
		if err := f.initHydration(infos); err != nil {
			f.logger.Warn("hydration initialization failed, continuing without hydration", "error", err)
			f.hydrationPath = ""
		}
	}

	// Continuously monitor the replica client for new LTX files.

View on GitHub (pinned to 4ed7a308f6)