gastownhall/beads · error
failed to acquire connection: %w
Error message
failed to acquire connection: %w
What it means
runDoltTransaction pins a single pooled connection for the whole logical transaction (SQL tx + DOLT_COMMIT must share one Dolt session). This error wraps the failure of s.db.Conn(ctx) — the pool could not hand out a connection, usually because the pool is exhausted and the context deadline expired, the Dolt SQL server refused/dropped the dial, or the context was canceled. It is the entry gate of every RunInTransaction write in the Dolt storage backend.
Source
Thrown at internal/storage/dolt/transaction.go:185
acquireStart := time.Now()
conn, err := s.db.Conn(ctx)
acquireMs := float64(time.Since(acquireStart).Microseconds()) / 1000.0
doltMetrics.connAcquireMs.Record(ctx, acquireMs)
// Detect pool-wait: if WaitCount increased, the pool was exhausted and
// this caller had to wait for a connection to become available.
if err == nil {
statsAfter := s.db.Stats()
if statsAfter.WaitCount > statsBefore.WaitCount {
doltMetrics.poolWaitCount.Add(ctx, statsAfter.WaitCount-statsBefore.WaitCount)
waitMs := float64(statsAfter.WaitDuration-statsBefore.WaitDuration) / float64(time.Millisecond)
doltMetrics.poolWaitMs.Record(ctx, waitMs)
}
}
if err != nil {
return fmt.Errorf("failed to acquire connection: %w", err)
}
defer conn.Close()
var currentBranch string
if err := conn.QueryRowContext(ctx, "SELECT active_branch()").Scan(¤tBranch); err != nil {
return fmt.Errorf("failed to read active branch: %w", err)
}
regularTx, err := conn.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("failed to begin regular tx: %w", err)
}
// The journal counter and rows must commit in the SAME SQL transaction as
// every mutation they describe. bd_events_journal and bd_events_seq are
// dolt_ignored, so on the default split-transaction shape they would land in
// the ignored transaction while the mutation lands in the regular one: a
// mixed durable+wisp callback would then make the two transactions contendView on GitHub (pinned to 71377f2769)
Solutions
- Check Dolt server reachability (host/port, auth) and that the DSN in s.connStr is valid
- Increase MaxOpenConns on the pool or reduce concurrent writers holding connections
- Check ctx deadlines — a too-short timeout makes pool waits fail; raise it or scope it wider
- Look for connection leaks (conns not closed) and long transactions that pin pool connections; retry the operation — runDoltTransaction setup failures are retried by withTransactionSetupRetry
Example fix
// before db.SetMaxOpenConns(1) // serializes all writers; pool waits expire // after db.SetMaxOpenConns(10) // allow concurrent pinned-connection transactions
Defensive patterns
Strategy: retry
Validate before calling
if err := db.PingContext(ctx); err != nil { return fmt.Errorf("dolt unreachable before write: %w", err) }
st := db.Stats()
if st.MaxOpenConnections > 0 && st.InUse >= st.MaxOpenConnections { return errors.New("pool exhausted; defer or widen pool") } Try / catch
err := store.RunInTransaction(ctx, msg, fn)
var netErr net.Error
if errors.As(err, &netErr) || errors.Is(err, context.DeadlineExceeded) {
// setup-phase failure: safe to retry
err = store.RunInTransaction(ctx, msg, fn)
} Prevention
- Size MaxOpenConns above your worst-case concurrent writers
- Keep per-operation context deadlines generous enough for pool waits
- Ping or health-check the store before long write batches
- Watch db.Stats() WaitCount to detect pool exhaustion early
When it happens
Trigger: Calling DoltStore.RunInTransaction (or any write API) when: the connection pool is exhausted and ctx expires before a connection frees up; the Dolt server is down or the TCP dial fails; the context is canceled mid-wait; or the connection was closed at dial time due to bad DSN/auth.
Common situations: Long-running callbacks holding connections while MaxOpenConns is small; many concurrent `bd` processes against one embedded/hosted Dolt server; server restart or network blip; a leaked connection elsewhere starving the pool.
Related errors
- acquire connection for gc: %w
- acquire connection for remote-ref prune: %w
- acquire connection for flatten: %w
- acquire connection for compact: %w
- ErrTransaction
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/11b1a1d28b61e433.
Report an issue: GitHub.