iflytek/astron-agent · critical

commit tenant bootstrap transaction failed

Error message

commit tenant bootstrap transaction failed: %w

What it means

After reconcileTenantBootstrapTransaction succeeds, the transaction is committed; if MySQL rejects the COMMIT (connection dropped mid-transaction, deadlock/rollback already applied, server restart) the failure is wrapped as 'commit tenant bootstrap transaction failed'. The deferred Rollback is a no-op at that point.

Solutions

  1. Check MySQL logs for connection kill / deadlock / lock-wait-timeout around the failure time and fix the root cause (usually contention on tb_app).
  2. Reduce the work inside the bootstrap transaction so it commits quickly, minimizing exposure to idle timeouts.
  3. Ensure retry/idempotency: reconcileTenantBootstrap should be safe to re-run, so restart the service after the DB issue clears.
  4. Verify network stability between the tenant service and MySQL (proxies, LB idle timeouts).

Example fix

// before
if err := transaction.Commit(); err != nil {
    return fmt.Errorf("commit tenant bootstrap transaction failed: %w", err)
}
// after: retry the whole reconcile on transient commit failure
if err := transaction.Commit(); err != nil {
    log.Printf("bootstrap commit failed, will retry: %v", err)
    return retryableError{cause: fmt.Errorf("commit tenant bootstrap transaction failed: %w", err)}
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight: ensure connection healthy before long transaction
if err := client.Ping(); err != nil {
    return fmt.Errorf("unhealthy connection before bootstrap commit: %w", err)
}

Try / catch

if err := transaction.Commit(); err != nil {
    log.Printf("bootstrap commit failed, re-running reconcile: %v", err)
    return retryReconcile(client, creds) // whole-flow retry; reconcile is idempotent
}

Prevention

When it happens

Trigger: initializeMysqlClient -> reconcileTenantBootstrap -> transaction.Commit() while the connection was lost, the server killed the transaction, or a deadlock had already rolled it back.

Common situations: Long-running bootstrap transaction spanning a MySQL failover/restart; wait_timeout reaped an idle connection; lock wait timeout on the reserved app row under replica contention during multi-pod startup.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/e0efd035d017b260. Report an issue: GitHub.

Appendix: source

Thrown at core/tenant/tools/database/bootstrap_credentials.go:73

	ctx := context.Background()
	transaction, err := client.BeginTx(ctx, nil)
	if err != nil {
		return fmt.Errorf("begin tenant bootstrap transaction failed: %w", err)
	}
	defer func() {
		_ = transaction.Rollback()
	}()

	if err := reconcileTenantBootstrapTransaction(
		ctx,
		sqlBootstrapTransaction{transaction: transaction},
		credentials,
	); err != nil {
		return err
	}
	if err := transaction.Commit(); err != nil {
		return fmt.Errorf("commit tenant bootstrap transaction failed: %w", err)
	}
	return nil
}

func reconcileTenantBootstrapTransaction(
	ctx context.Context,
	transaction bootstrapTransaction,
	credentials config.TenantBootstrapCredentials,
) error {
	if transaction == nil {
		return errors.New("tenant bootstrap transaction is nil")
	}
	if err := credentials.Validate(); err != nil {
		return fmt.Errorf("invalid tenant bootstrap credentials: %w", err)
	}

	now := time.Now().Format("2006-01-02 15:04:05")
	if err := ensureAndLockTenantBootstrapApp(ctx, transaction, credentials, now); err != nil {

View on GitHub (pinned to 5e758547a8)