benbjohnson/litestream · error

get database position: %w

Error message

get database position: %w

What it means

Litestream's checkDatabaseBehindReplica compares the local database position (derived from local L0 LTX files) against the remote replica position. This error wraps any failure from db.Pos(), which scans local LTX state to compute the current TXID. It means Litestream could not determine the local transaction position, so it cannot safely check whether the database is behind its replica.

Source

Thrown at db.go:1593

	if fi, err := os.Stat(db.WALPath()); err == nil && fi.Size() >= WALHeaderSize {
		return nil
	}

	// Otherwise create transaction that updates the internal litestream table.
	return db.bumpLitestreamSeq(ctx)
}

// checkDatabaseBehindReplica detects when a database has been restored to an
// earlier state and the replica has a higher TXID. This handles issue #781.
//
// If detected, it clears local L0 files and fetches the latest L0 LTX file
// from the replica to establish a baseline. The next DB.sync() will detect
// the mismatch and trigger a snapshot at the current database state.
func (db *DB) checkDatabaseBehindReplica(ctx context.Context) error {
	// Get database position from local L0 files
	dbPos, err := db.Pos()
	if err != nil {
		return fmt.Errorf("get database position: %w", err)
	}

	// Get replica position from remote
	replicaInfo, err := db.Replica.MaxLTXFileInfo(ctx, 0)
	if err != nil {
		return fmt.Errorf("get replica position: %w", err)
	} else if replicaInfo.MaxTXID == 0 {
		return nil // No remote replica data yet
	}

	// Check if database is behind replica
	if dbPos.TXID >= replicaInfo.MaxTXID {
		return nil // Database is ahead or equal
	}

	db.Logger.Info("detected database behind replica",
		"db_txid", dbPos.TXID,
		"replica_txid", replicaInfo.MaxTXID)

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Check filesystem health and permissions on the DB's LTX directory (ls -l, df -h); fix disk-full or permission problems.
  2. Run `litestream ltx -level 0` (or inspect the LTX dir) to find corrupt/unreadable LTX files.
  3. If local LTX state is corrupt, run `litestream reset` for the database to clear local LTX state and re-snapshot from the replica.
  4. Inspect the wrapped cause (%w) in logs — the underlying os/stat error names the exact file or path that failed.

Example fix

// before: silent confusion about why position fails
log.Println("sync failed")
// after: log the wrapped cause to find the offending file
log.Printf("sync failed: %v", err) // e.g. "get database position: open .../ltx/0/...: permission denied"
Defensive patterns

Strategy: try-catch

Validate before calling

// Check local LTX dir is readable before running
if _, err := os.ReadDir(dbPath + "/ltx/0"); err != nil {
    return fmt.Errorf("local L0 dir unreadable: %w", err)
}

Type guard

// Go has no runtime type guard; verify the underlying error
var pe *os.PathError
if errors.As(err, &pe) { log.Printf("path %s failed: %v", pe.Path, pe.Err) }

Try / catch

if err := db.SyncAndWait(ctx); err != nil {
    if strings.Contains(err.Error(), "get database position") {
        log.Printf("local LTX state unreadable, consider `litestream reset`: %v", err)
    }
}

Prevention

When it happens

Trigger: db.sync() (or the periodic sync/check path) invokes checkDatabaseBehindReplica and db.Pos() fails — e.g. the database's LTX directory is unreadable, corrupt L0 files exist, or the position cache is invalid and re-deriving the position fails.

Common situations: Corrupted or partially-written LTX files under the DB's LTX directory (disk full, crash mid-write); wrong db path/cdirectory permissions after moving the data dir; running litestream against a directory whose L0 files were manually deleted or edited; filesystem I/O errors on the volume hosting the database.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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