benbjohnson/litestream · error

read position after sync: %w

Error message

read position after sync: %w

What it means

Store.SyncDB failed after a successful sync because db.MaxLTX() could not read the post-sync replication position. Since the sync succeeded, this usually indicates a problem reading local LTX position metadata or an unexpected internal state, not a replication failure. The wrapped error is returned with %w.

Source

Thrown at store.go:460

	_, beforeTXID, err := db.MaxLTX()
	if err != nil {
		return SyncDBResult{}, fmt.Errorf("read position before sync: %w", err)
	}

	if wait {
		if err := db.SyncAndWait(ctx); err != nil {
			return SyncDBResult{}, fmt.Errorf("sync database: %w", err)
		}
	} else {
		if err := db.Sync(ctx); err != nil {
			return SyncDBResult{}, fmt.Errorf("sync database: %w", err)
		}
	}

	_, afterTXID, err := db.MaxLTX()
	if err != nil {
		return SyncDBResult{}, fmt.Errorf("read position after sync: %w", err)
	}

	var replicatedTXID uint64
	if db.Replica != nil {
		replicatedTXID = uint64(db.Replica.Pos().TXID)
	}

	return SyncDBResult{
		TXID:           uint64(afterTXID),
		ReplicatedTXID: replicatedTXID,
		Changed:        afterTXID > beforeTXID,
	}, nil
}

// FindDB returns the database with the given path.
func (s *Store) FindDB(path string) *DB {
	s.mu.Lock()
	defer s.mu.Unlock()

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Re-run SyncDB; if the before-sync read (store.go:445) also fails, treat it as a local-state problem rather than a sync problem.
  2. Inspect local LTX/replica position files for corruption; run litestream reset to clear corrupted local state for that database.
  3. Check filesystem health and permissions on the Litestream data directory.
  4. Avoid closing/unregistering the DB concurrently with SyncDB calls; serialize lifecycle operations.

Example fix

// before
res, err := store.SyncDB(ctx, path, true)
// after
res, err := store.SyncDB(ctx, path, true)
if err != nil {
    // sync may have succeeded; verify position before retrying aggressively
    log.Printf("SyncDB %s: %v", path, err)
    return err
}
Defensive patterns

Strategy: try-catch

Try / catch

res, err := store.SyncDB(ctx, path, true)
if err != nil {
    // sync may have succeeded; check error position to decide retry
    log.Printf("SyncDB %s failed: %v", path, err)
    return err
}

Prevention

When it happens

Trigger: SyncDB(ctx, path, wait) completes db.Sync/SyncAndWait successfully, but the subsequent db.MaxLTX() call errors while enumerating local LTX files to compute the after TXID.

Common situations: Local LTX metadata corruption, filesystem errors after the sync (disk removed, permissions changed mid-call), or a bug/race where the DB was closed concurrently between sync and position read.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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