SigNoz/signoz · error · errors.base

internal

internal

Error message

failed to start transaction

What it means

DeleteUser starts a multi-statement transaction by calling BeginTx; if the database cannot open a new transaction this internal error is returned before any user data is touched. Common root causes are lost connections, exhausted connection pools, or a canceled/invalid context. Because BeginTx acquires a connection from the pool, pool starvation is a frequent culprit.

Source

Thrown at pkg/modules/user/impluser/store.go:148

	err := store.
		sqlstore.
		BunDBCtx(ctx).
		NewSelect().
		Model(&users).
		Where("org_id = ?", orgID).
		Scan(ctx)
	if err != nil {
		return nil, err
	}

	return users, nil
}

func (store *store) DeleteUser(ctx context.Context, orgID string, id string) error {
	tx, err := store.sqlstore.BunDB().BeginTx(ctx, nil)
	if err != nil {
		return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to start transaction")
	}

	defer func() {
		_ = tx.Rollback()
	}()

	// get the password id

	var password types.FactorPassword
	err = tx.NewSelect().
		Model(&password).
		Where("user_id = ?", id).
		Scan(ctx)
	if err != nil && err != sql.ErrNoRows {
		return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to delete password")
	}

	// delete reset password request

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Inspect wrapped error: driver.ErrBadConn or context.Canceled points to pool/context issues
  2. Increase or tune connection pool settings and idle timeouts on the sqlstore
  3. Retry the DeleteUser call with backoff if the error is transient connectivity
  4. Verify DB is accepting writes (not in recovery/read-only)

Example fix

// before
err := store.DeleteUser(ctx, orgID, userID)

// after
if err := store.DeleteUser(ctx, orgID, userID); err != nil {
    if strings.Contains(err.Error(), "cannot begin transaction") {
        time.Sleep(200 * time.Millisecond)
        err = store.DeleteUser(ctx, orgID, userID) // one retry
    }
}
Defensive patterns

Strategy: retry

Validate before calling

if ctx.Err() != nil { return ctx.Err() }
if err := store.sqlstore.BunDB().PingContext(ctx); err != nil { return err }

Type guard

func isBeginTxFailure(err error) bool {
    return err != nil && strings.Contains(err.Error(), "cannot begin transaction")
}

Try / catch

err := firstAttempt
if isBeginTxFailure(err) {
    time.Sleep(200*time.Millisecond)
    err = store.DeleteUser(ctx, orgID, id)
}
return err

Prevention

When it happens

Trigger: Calling DeleteUser when the DB connection pool is saturated, the server restarted/closed connections, ctx is already canceled, or the database is in recovery/read-only mode.

Common situations: Connection pool max size too small for concurrent delete requests, Postgres restart or failover, long-running transactions holding all pool connections, k8s liveness probes canceling request contexts.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/b8b3c9d76e55b97f. Report an issue: GitHub.