benbjohnson/litestream · error

no replica client configured

Error message

no replica client configured

What it means

DB.EnsureExists(ctx) requires both a Replica and a Replica.Client. This error means db.Replica exists but its storage client was never initialized, so litestream cannot talk to the replica destination to restore the database.

Source

Thrown at db.go:738

	if err := db.Sync(ctx); err != nil {
		return fmt.Errorf("db sync: %w", err)
	}
	if err := db.Replica.Sync(ctx); err != nil {
		return fmt.Errorf("replica sync: %w", err)
	}
	return nil
}

// EnsureExists restores the database from the configured replica if the local
// database file does not exist. If no backup is available, it returns nil and
// a fresh database will be created on Open(). Must be called before Open().
func (db *DB) EnsureExists(ctx context.Context) error {
	if db.Replica == nil {
		return fmt.Errorf("no replica configured")
	}
	if db.Replica.Client == nil {
		return fmt.Errorf("no replica client configured")
	}

	if _, err := os.Stat(db.Path()); err == nil {
		return nil
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("stat database: %w", err)
	}

	if dir := filepath.Dir(db.Path()); dir != "." {
		if err := os.MkdirAll(dir, 0o750); err != nil {
			return fmt.Errorf("create parent directory: %w", err)
		}
	}

	opt := NewRestoreOptions()
	opt.OutputPath = db.Path()
	opt.IntegrityCheck = IntegrityCheckQuick

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Initialize the client: assign the appropriate ReplicaClient (e.g. &s3.ReplicaClient{...} or via config load) to db.Replica.Client.
  2. Prefer loading replicas from config (which wires the client) rather than hand-constructing them.
  3. If you implement a custom backend, follow docs/REPLICA_CLIENT_GUIDE.md and register it so the client is created from config.
  4. Guard: check db.Replica.Client != nil before EnsureExists and return a clear config error.

Example fix

// before
db.Replica = litestream.NewReplica(db, replicaConfig)
db.EnsureExists(ctx) // error: no replica client configured
// after
db.Replica = litestream.NewReplica(db, replicaConfig)
db.Replica.Client = s3.NewReplicaClient() // configure bucket/region/creds
if err := db.Replica.Client.Init(ctx); err != nil { return err }
db.EnsureExists(ctx)
Defensive patterns

Strategy: validation

Validate before calling

if db.Replica == nil || db.Replica.Client == nil {
    return errors.New("replica client not initialized; build replica via config")
}

Try / catch

if err := db.EnsureExists(ctx); err != nil {
    if strings.Contains(err.Error(), "no replica client configured") {
        return errors.New("initialize db.Replica.Client before EnsureExists")
    }
    return err
}

Prevention

When it happens

Trigger: Calling db.EnsureExists(ctx) on a DB whose Replica was constructed manually (e.g. litestream.NewReplica without calling replica.Client assignment / init) or whose client failed to initialize from config.

Common situations: Library users building Replica structs directly instead of via config loading, forgetting to set Client (e.g. s3.NewReplicaClient()); a custom replica_client.go backend not wired into the client factory; config loaded with an unsupported replica type yielding a nil client.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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