gastownhall/beads · error

failed to acquire ignored tx connection: %w

Error message

failed to acquire ignored tx connection: %w

What it means

On the fresh-dial fallback path, db.Conn(ctx) must dial the Dolt SQL server for the dedicated ignored-tables connection. This error wraps that acquisition failure — dial error, auth failure, TLS mismatch, or ctx timeout/cancellation while connecting. The intermediate pool is closed before returning, so no resource leaks beyond the failed dial.

Source

Thrown at internal/storage/dolt/transaction.go:330

		// A stale pooled connection or a session on another branch: a fresh
		// dial always worked before, so discard this one (its session state is
		// untouched) and fall through to the fallback.
		_ = conn.Close()
	}

	// Fallback: a dedicated single-connection pool, paying the fresh dial the
	// borrow path exists to avoid.
	doltMetrics.ignoredTxFreshPool.Add(ctx, 1)
	db, err := sql.Open("mysql", s.connStr)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to open ignored tx connection: %w", err)
	}
	db.SetMaxOpenConns(1)

	conn, err := db.Conn(ctx)
	if err != nil {
		_ = db.Close()
		return nil, nil, fmt.Errorf("failed to acquire ignored tx connection: %w", err)
	}

	tx, err = beginTxOnConn(ctx, conn, branch)
	if err != nil {
		_ = conn.Close()
		_ = db.Close()
		return nil, nil, err
	}

	return func() { _ = conn.Close(); _ = db.Close() }, tx, nil
}

// borrowConnForIgnoredTx returns a second connection borrowed from the main pool
// for the ignored-tables transaction, or nil if borrowing is unsafe or would
// block. The caller falls back to a dedicated single-connection pool on nil.
func (s *DoltStore) borrowConnForIgnoredTx(ctx context.Context) *sql.Conn {
	st := s.db.Stats()
	// MaxOpenConns==1: the caller already pinned the pool's only connection for

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify the Dolt server is up and reachable (nc/curl the host:port, or `mysql` client connect)
  2. Check credentials and TLS settings in the DSN
  3. Check ctx deadlines — a fresh dial needs the full handshake time; widen the timeout
  4. Note the borrow fast path already failed: pool exhaustion plus dial failure usually means server/network trouble, fix that root cause

Example fix

// before
ctx, cancel := context.WithTimeout(ctx, 50*time.Millisecond) // too short for a fresh handshake
// after
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
Defensive patterns

Strategy: retry

Validate before calling

if err := db.PingContext(ctx); err != nil { return fmt.Errorf("dolt server unreachable: %w", err) }

Try / catch

if err != nil && (errors.Is(err, context.DeadlineExceeded) || isDialErr(err)) {
    return retryWithBackoff(ctx, op) // dial failures are safe to retry pre-callback
}

Prevention

When it happens

Trigger: Dolt server unreachable (down, wrong host/port, firewall) at fallback time; wrong credentials or missing TLS config in s.connStr; ctx canceled/expired during the fresh dial; server at max-connection limit.

Common situations: Pool exhausted AND the network is degraded (borrow skipped, fresh dial also fails); credentials rotated; embedded Dolt server not started; IPv6/localhost resolution differences for the DSN host.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/5b454c4a2c610031. Report an issue: GitHub.