benbjohnson/litestream · critical

cannot open store: %w

Error message

cannot open store: %w

What it means

`Store.Open` initializes the replication store: opens/configures all databases from the config and starts their monitors. If any database fails to open (bad path, locked file, invalid replica config, storage client errors), Run wraps the failure with "cannot open store". This is the main startup failure point for the replicate command.

Source

Thrown at cmd/litestream/replicate.go:292

		}
		c.Store.Heartbeat = litestream.NewHeartbeatClient(c.Config.HeartbeatURL, interval)
	}

	// Disable all background monitors when running once.
	// This must be done after config settings are applied.
	if c.once {
		c.Store.CompactionMonitorEnabled = false
		c.Store.L0RetentionCheckInterval = 0
		for _, db := range dbs {
			db.MonitorInterval = 0
			if db.Replica != nil {
				db.Replica.MonitorEnabled = false
			}
		}
	}

	if err := c.Store.Open(ctx); err != nil {
		return fmt.Errorf("cannot open store: %w", err)
	}

	if !c.Store.RetentionEnabled {
		slog.Warn("retention disabled; cloud provider lifecycle policies must handle retention",
			"hint", "idle databases that stop receiving writes will not generate new snapshots and may lose backup coverage if cloud retention expires")
	}

	// Start control server if socket is enabled
	if c.Config.Socket.Enabled {
		c.Server = litestream.NewServer(c.Store)
		c.Server.SocketPath = c.Config.Socket.Path
		c.Server.SocketPerms = c.Config.Socket.Permissions
		c.Server.PathExpander = expand
		c.Server.Version = Version
		if err := c.Server.Start(); err != nil {
			slog.Warn("failed to start control server", "error", err)
		}
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Read the wrapped inner error for the root cause (permissions, missing file, storage auth)
  2. Verify the config file DB paths exist and are readable by the litestream process
  3. Test storage credentials/endpoint (e.g. `litestream ltx` or aws CLI against the bucket)
  4. Validate the config with `litestream -config <file> ...` dry parsing before running

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-flight checks before starting litestream
[ -f "$DB_PATH" ] || { echo "db missing: $DB_PATH" >&2; exit 1; }
[ -r "$DB_PATH" ] && [ -w "$DB_PATH" ] || { echo "db not rw" >&2; exit 1; }
# verify storage access (example for s3)
aws s3 ls "s3://$BUCKET/" >/dev/null || { echo "storage auth failed" >&2; exit 1; }

Try / catch

// Go library usage
cmd := litestream.NewReplicateCommand()
if err := cmd.Run(ctx); err != nil {
    var storeErr *fmt.WrapError // inspect wrapped cause via errors.Unwrap chain
    for e := err; e != nil; e = errors.Unwrap(e) {
        log.Printf("cause: %v", e)
    }
    return fmt.Errorf("store startup failed: %w", err)
}

Prevention

When it happens

Trigger: Calling `litestream.ReplicateCommand.Run` where `c.Store.Open(ctx)` returns an error — e.g. configured DB file cannot be opened, a replica client fails to initialize (bad credentials/endpoint), or invalid config values.

Common situations: Wrong DB path in config file, S3 credentials missing/expired, unreachable storage endpoint at startup, malformed config causing invalid DB construction.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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