temporalio/temporal · error
error building DSN: %w
Error message
error building DSN: %w
What it means
Wrapped in createDBConnection when buildDSN fails while constructing the SQLite data source name. buildDSN derives the DSN from the SQL config (database file path and ConnectAttributes), so this indicates invalid or missing SQLite configuration. The wrapped error from buildDSN states the exact reason.
Source
Thrown at common/persistence/sql/sqlplugin/sqlite/plugin.go:84
return nil, err
}
db := newDB(dbKind, cfg.DatabaseName, conn, nil, logger)
db.OnClose(func() { p.connPool.Close(cfg) }) // remove reference
return db, nil
}
// createDBConnection creates a returns a reference to a logical connection to the
// underlying SQL database. The returned object is tied to a single
// SQL database and the object can be used to perform CRUD operations on
// the tables in the database.
func (p *plugin) createDBConnection(
cfg *config.SQL,
_ resolver.ServiceResolver,
logger log.Logger,
) (*sqlx.DB, error) {
dsn, err := buildDSN(cfg)
if err != nil {
return nil, fmt.Errorf("error building DSN: %w", err)
}
db, err := sqlx.Connect(goSQLDriverName, dsn)
if err != nil {
return nil, err
}
// Connection pool settings.
//
// By default, SQLite only supports a single writer at a time (see
// https://github.com/mattn/go-sqlite3#faq). Without WAL (Write-Ahead Logging)
// mode, concurrent connections will encounter "database is locked" errors.
// With WAL mode enabled (journal_mode=wal), SQLite supports concurrent readers
// alongside a single writer, making multiple connections safe and beneficial
// for throughput.
//
// These settings mirror the behavior of the MySQL and PostgreSQL plugins:
// respect the user's config values when set, otherwise default to 1 forView on GitHub (pinned to bde624efd1)
Solutions
- Fix cfg.ConnectAttributes entries to be valid key=value pairs.
- Confirm the database name/path in the SQL config is set and writable for the sqlite file.
- Compare your config against a known-good sqlite example in config/.
- Check the inner buildDSN error for the specific parse failure.
Example fix
// before
connectAttributes: {"cache": "shared", "mode": "ro" "bad"}
// after
connectAttributes: {"cache": "shared", "mode": "ro"} Defensive patterns
Strategy: validation
Validate before calling
// Go: pre-validate sqlite connect attributes
for _, attr := range cfg.ConnectAttributes {
if len(strings.Split(attr, "=")) < 2 {
return fmt.Errorf("invalid sqlite connect attribute %q: expected key=value", attr)
}
} Try / catch
// Go
if err != nil && strings.Contains(err.Error(), "error building DSN") {
return fmt.Errorf("check sqlite config (ConnectAttributes, database path): %w", err)
} Prevention
- Keep ConnectAttributes as strict key=value pairs
- Verify the sqlite file path exists and is writable
- Lint your config YAML against a known-good sqlite example
- Don't reuse mysql/postgres connect attributes in sqlite configs
When it happens
Trigger: Starting the persistence layer with sqlite driver when cfg.ConnectAttributes contains malformed URI parameters (e.g. 'x=y=z' or unparseable key=value pairs) or the config otherwise prevents DSN construction.
Common situations: Misconfigured sqlite ConnectAttributes in the Temporal config YAML; typos like missing '=' in connection attributes; using sqlite in environments where config was copied from mysql/postgres setups.
Related errors
- duplicate connection attr: %v:%v, %v:%v
- requires a StartTime or CloseTime
- only one of certData or certFile properties should be specif
- missing current cluster metadata under clusterMetadata.Clust
- hosts are missing in static hosts for service: ${service}
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/7fde2f169c2258ab.
Report an issue: GitHub.