iflytek/astron-agent · critical
begin tenant bootstrap transaction failed
Error message
begin tenant bootstrap transaction failed: %w
What it means
reconcileTenantBootstrap opens a MySQL transaction via client.BeginTx to reconcile the bootstrap app/credentials; if the transaction cannot even be started (DB unreachable, too many connections, server shutdown) the error is wrapped as 'begin tenant bootstrap transaction failed'.
Solutions
- Verify MySQL is reachable (docker compose ps, mysql -h ... -e 'SELECT 1') and the tenant service DSN/host/port are correct.
- Retry after MySQL is ready — add readiness gating or backoff so initializeMysqlClient does not race DB startup.
- Check max_connections and for leaked transactions/connection pool misconfiguration in the tenant service.
- Inspect the wrapped cause (%w chain) to distinguish network refusal from auth or pool errors.
Example fix
// before
transaction, err := client.BeginTx(ctx, nil)
if err != nil { return fmt.Errorf("begin tenant bootstrap transaction failed: %w", err) }
// after: gate on DB readiness with retry
if err := waitUntilMySQLReady(ctx, client, 30*time.Second); err != nil {
return fmt.Errorf("mysql not ready for bootstrap: %w", err)
}
transaction, err := client.BeginTx(ctx, nil)
if err != nil { return fmt.Errorf("begin tenant bootstrap transaction failed: %w", err) } Defensive patterns
Strategy: retry
Validate before calling
if err := client.Ping(); err != nil {
return fmt.Errorf("mysql unreachable before bootstrap: %w", err)
} Try / catch
for attempt := 0; attempt < 5; attempt++ {
err := reconcileTenantBootstrap(client, creds)
if err == nil { break }
if strings.Contains(err.Error(), "begin tenant bootstrap transaction failed") {
time.Sleep(time.Duration(attempt+1) * 2 * time.Second)
continue
}
return err
} Prevention
- Gate service startup on MySQL readiness (depends_on healthcheck / readiness probe).
- Set sane pool limits so bootstrap never fights max_connections.
- Use short-lived bootstrap transactions to avoid idle disconnects.
When it happens
Trigger: initializeMysqlClient -> reconcileTenantBootstrap while MySQL is down, unreachable, refusing connections, or has exhausted max_connections so BEGIN fails.
Common situations: MySQL container not yet ready during service startup; wrong DSN/host in tenant service config; connection pool exhausted by leaked transactions; MySQL restarted mid-deploy.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- commit tenant bootstrap transaction failed
- lock tenant bootstrap app failed
- adopt tenant bootstrap credential failed
- check tenant bootstrap API key ownership failed
- check tenant bootstrap managed credential failed
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/8794bd02eecc7863.
Report an issue: GitHub.
Appendix: source
Thrown at core/tenant/tools/database/bootstrap_credentials.go:59
) bootstrapRowScanner {
return transaction.transaction.QueryRowContext(ctx, query, args...)
}
func reconcileTenantBootstrap(
client *sql.DB,
credentials config.TenantBootstrapCredentials,
) error {
if client == nil {
return errors.New("mysql client is nil")
}
if err := credentials.Validate(); err != nil {
return fmt.Errorf("invalid tenant bootstrap credentials: %w", err)
}
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
}
View on GitHub (pinned to 5e758547a8)