benbjohnson/litestream · error

clear write buffer: %w

Error message

clear write buffer: %w

What it means

This error is returned after a successful sync when VFSFile.clearWriteBuffer() fails. Litestream's VFS layer stages dirty page data in a temporary write-buffer file for durability; after an LTX transaction commits, the buffer must be cleared (truncated/reset) so it can accumulate the next transaction's pages. The wrap preserves the underlying OS or I/O error from that cleanup step.

Source

Thrown at vfs.go:2056

		f.cache.Add(pgno, cachedData)
	}

	// Apply synced pages to hydrated file if hydration is complete
	// Must be done before clearing f.dirty since we need the page offsets
	if f.hydrator != nil && f.hydrator.Complete() {
		if err := f.applySyncedPagesToHydratedFile(); err != nil {
			f.logger.Error("failed to apply synced pages to hydrated file", "error", err)
			// Don't fail the sync - hydration will catch up on next poll
		}
	}

	// Clear dirty pages
	f.dirty = make(map[uint32]int64)

	// Clear write buffer after successful sync
	if err := f.clearWriteBuffer(); err != nil {
		f.logger.Error("failed to clear write buffer", "error", err)
		return fmt.Errorf("clear write buffer: %w", err)
	}

	return nil
}

// checkForConflict checks if the remote has newer transactions than expected.
// Must be called with f.mu held.
func (f *VFSFile) checkForConflict(ctx context.Context) error {
	// Get latest remote position
	itr, err := f.client.LTXFiles(ctx, 0, f.expectedTXID, false)
	if err != nil {
		return fmt.Errorf("check remote position: %w", err)
	}
	defer itr.Close()

	var remoteTXID ltx.TXID
	for itr.Next() {
		info := itr.Item()

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Check disk space and filesystem health on the volume holding the buffer file (inspect the underlying error wrapped by this message for ENOSPC/EIO).
  2. Verify nothing else deletes or locks the buffer file while the database is open; exclude it from tmp-cleanup jobs.
  3. Restart the process: initWriteBufferWithLock truncates and rebuilds the buffer on open, clearing stale state.
  4. If the wrapped error is permission-related, fix ownership/mode of the buffer directory (0755) and file (0644).

Example fix

// before: buffer file cleaned up externally
// /etc/tmpfiles.d/cleanup.conf
// D /var/tmp/litestream 0755 root root -
// after: persist buffer dir outside tmp cleaner scope
// bufferPath: /var/lib/litestream/buffers/db.buffer
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: check volume writability before opening the DB
if f, err := os.Stat(filepath.Dir(bufferPath)); err != nil || !f.IsDir() { return fmt.Errorf("buffer dir missing: %w", err) }

Try / catch

if err := db.Sync(ctx); err != nil {
    if strings.Contains(err.Error(), "clear write buffer") {
        logger.Error("buffer cleanup failed; restarting DB handle to rebuild buffer", "err", err)
        // reopen DB to re-init write buffer
    }
    return err
}

Prevention

When it happens

Trigger: VFSFile sync succeeds remotely but the subsequent clearWriteBuffer() call fails to truncate or reset the buffer file (disk I/O error, file deleted or locked underneath the VFS, disk full, stale file descriptor after restart).

Common situations: Disk-full conditions on the node hosting the buffer file; the buffer file removed by tmp cleaners or another process; running inside containers with read-only or small tmp volumes; crash-recovery leaving the buffer file in a bad state.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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