benbjohnson/litestream · error

replica required before opening database

Error message

replica required before opening database

What it means

This error is returned by DB.Open (db.go) when the database object is opened without a Replica assigned. Litestream requires every database to have exactly one replication destination, so opening without one is a programming/configuration error rather than a runtime failure. It is a fail-fast validation performed at open time, before any file or network resources are touched.

Source

Thrown at db.go:782

	db.Logger.Info("database restored from backup", "path", db.Path())
	return nil
}

// Open initializes the background monitoring goroutine.
func (db *DB) Open() (err error) {
	db.mu.Lock()
	if db.opened {
		db.mu.Unlock()
		return nil // already open
	}
	// Recreate context for fresh start (handles reopen after close)
	db.ctx, db.cancel = context.WithCancel(context.Background())
	db.mu.Unlock()

	// Validate fields on database.
	if db.Replica == nil {
		return fmt.Errorf("replica required before opening database")
	}
	if db.Replica.Client == nil {
		return fmt.Errorf("replica client required before opening database")
	}
	if db.MinCheckpointPageN <= 0 {
		return fmt.Errorf("minimum checkpoint page count required")
	}

	// Clear old temporary files that my have been left from a crash.
	if err := removeTmpFiles(db.metaPath); err != nil {
		return fmt.Errorf("cannot remove tmp files: %w", err)
	}

	// Set the compactor client once before starting any goroutines.
	db.compactor.VerifyCompaction = db.VerifyCompaction
	db.compactor.RetentionEnabled = db.RetentionEnabled
	db.compactor.client = db.Replica.Client

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Set db.Replica (with a configured ReplicaClient) before calling Open().
  2. If using a config file, add a replica section (e.g. s3, sftp, file) under the database.
  3. Check the construction code for early returns that leave Replica nil, and reopen-after-close paths that rebuild the DB incompletely.

Example fix

// before
db := litestream.NewDB("/data/app.db")
if err := db.Open(); err != nil { ... }
// after
db := litestream.NewDB("/data/app.db")
client := s3.NewReplicaClient()
client.Bucket = "my-bucket"
db.Replica = litestream.NewReplica(db, "s3")
db.Replica.Client = client
if err := db.Open(); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

if db.Replica == nil {
    return fmt.Errorf("db %s: replica must be set before Open()", db.Path())
}

Prevention

When it happens

Trigger: Constructing a litestream.DB struct programmatically (library API) and calling Open() without setting db.Replica, or building a DB from a config that has no replica section.

Common situations: Embedding Litestream in a Go application and forgetting to call db.NewReplica(...) / attach a replica client; a YAML config that defines a database path but omits the replica block; code paths that reopen a DB after Close and reconstruct it incorrectly.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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