benbjohnson/litestream · error
open database: %w
Error message
open database: %w
What it means
In generateLoad, `sql.Open("sqlite3", c.DB+"?_journal_mode=WAL")` failed and the error is wrapped as "open database". Note that database/sql's Open is lazy and mostly validates the DSN/driver; real connection failures usually surface on first use, so this error typically indicates a bad DSN, an unregistered driver (build-tag/CGO issue with the sqlite3 driver), or an immediate driver-level open failure.
Source
Thrown at cmd/litestream-test/load.go:80
}
slog.Info("Starting load generation",
"db", c.DB,
"write_rate", c.WriteRate,
"duration", c.Duration,
"pattern", c.Pattern,
"payload_size", c.PayloadSize,
"read_ratio", c.ReadRatio,
"workers", c.Workers,
)
return c.generateLoad(ctx)
}
func (c *LoadCommand) generateLoad(ctx context.Context) error {
db, err := sql.Open("sqlite3", c.DB+"?_journal_mode=WAL")
if err != nil {
return fmt.Errorf("open database: %w", err)
}
defer db.Close()
db.SetMaxOpenConns(c.Workers + 1)
db.SetMaxIdleConns(c.Workers)
if err := c.ensureTestTable(db); err != nil {
return fmt.Errorf("ensure test table: %w", err)
}
ctx, cancel := context.WithTimeout(ctx, c.Duration)
defer cancel()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
go func() {
<-sigChan
slog.Info("Received interrupt signal, stopping load generation")View on GitHub (pinned to 4ed7a308f6)
Solutions
- Check that the -db path is valid, readable, and contains no characters (like '?') that would break the DSN; rename or quote/escape if needed.
- Verify the binary was built with the sqlite3 driver imported (blank import of the driver package); rebuild with CGO or the driver's pure-Go variant as required.
- Run `litestream-test load -db <path>` on a known-good database (created by populate) to isolate DSN vs environment issues.
Example fix
// before
db, err := sql.Open("sqlite3", c.DB+"?_journal_mode=WAL")
if err != nil {
return fmt.Errorf("open database: %w", err)
}
// after — surface driver/DSN issues eagerly with a ping
db, err := sql.Open("sqlite3", c.DB+"?_journal_mode=WAL")
if err != nil {
return fmt.Errorf("open database: %w", err)
}
if err := db.Ping(); err != nil {
return fmt.Errorf("open database: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check the path and DSN before invoking
if (dbPath.includes("?")) throw new Error("DB path must not contain DSN-significant characters: " + dbPath); Try / catch
try {
await run("litestream-test", ["load", "-db", dbPath]);
} catch (e) {
if (String(e).includes("open database")) {
console.error(`Failed to open ${dbPath}: check the sqlite3 driver build (CGO/pure-Go) and that the path is DSN-safe`);
}
throw e;
} Prevention
- Keep DB paths free of '?' and other DSN-significant characters.
- Build the harness with the sqlite3 driver properly imported/registered.
- Smoke-test with a database created by populate before production runs.
When it happens
Trigger: Calling `litestream-test load -db <path>` where the resulting DSN `<path>?_journal_mode=WAL` is rejected by the driver, the sqlite3 driver is not imported/available in the binary, or the driver immediately fails to open the file (e.g., unreadable path).
Common situations: Special characters in the DB path corrupting the DSN; a build without the sqlite3 driver registered; file permissions blocking the driver's open; very unusual DSN combos when the path itself contains '?' or other DSN-significant characters.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- open database: %w
- database does not exist: %w
- ensure test table: %w
- populate database: %w
- set page size: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/635b9b30d8187543.
Report an issue: GitHub.