iflytek/astron-agent · error
adopt tenant bootstrap credential failed
Error message
adopt tenant bootstrap credential failed: %w
What it means
adoptTenantBootstrapCredential wraps a failure of the UPDATE that marks an existing (older-release, manually created via the public API) tb_auth credential row as tenant-managed by setting extend=tenantBootstrapManagedMarker. Any MySQL/driver error from ExecContext is wrapped with %w. The reconciliation is aborted so the credential is not silently left half-adopted.
Solutions
- Inspect the wrapped driver error in tenant service logs (deadlock vs timeout vs connection loss).
- For deadlock/lock-wait-timeout, simply retry: the whole reconcile runs in a transaction and is idempotent.
- Ensure the reconcile transaction is executed against the primary, not a read-only replica.
- Check MySQL error log for InnoDB deadlock details and serialize concurrent bootstrap runs (e.g. advisory lock).
- Verify connection-pool sizing (max_open_conns) is adequate for the number of concurrent reconcilers.
Example fix
// before
if err := reconcileTenantBootstrapTransaction(ctx, tx, creds); err != nil {
return err
}
// after: retry transient DB failures
for i := 0; i < 3; i++ {
err := reconcileTenantBootstrapTransaction(ctx, tx, creds)
if err == nil || !isRetryableDBError(err) {
return err
}
time.Sleep(time.Duration(1<<i) * 100 * time.Millisecond)
} Defensive patterns
Strategy: retry
Try / catch
if err := reconcile(ctx, tx, creds); err != nil {
if isDeadlockOrTimeout(err) {
return retryWithBackoff(ctx, func() error { return reconcile(ctx, tx, creds) })
}
return err
} Prevention
- Keep reconcile transactions short to reduce lock contention.
- Run only one reconciler per deployment (leader election).
- Point writes at the primary, never a read replica.
- Retry idempotent transactional operations on transient DB errors.
When it happens
Trigger: transaction.ExecContext("UPDATE tb_auth SET extend=?, update_time=? WHERE app_id=? AND api_key=? AND api_secret=? AND is_delete=0 AND COALESCE(extend,'')<>?" ) returns a non-nil error during reconcileTenantBootstrapTransaction — e.g. deadlocked with another writer, lock wait timeout, connection reset, or read-only replica.
Common situations: Concurrent tenant bootstrap runs deadlock on the same tb_auth rows; the DB connection pool is exhausted; the statement is routed to a read-only replica; the table is corrupted or under schema migration (ALTER TABLE metadata lock).
Related errors
- check tenant bootstrap managed credential failed
- mysql username is empty
- mysql url is empty
- disable published legacy tenant credential failed
- locked tenant bootstrap app does not match the reserved…
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/22bf4f4b3aca8a6f.
Report an issue: GitHub.
Appendix: source
Thrown at core/tenant/tools/database/bootstrap_credentials.go:229
) error {
// A strong pair explicitly configured by the deployment may already have
// been created through Tenant's public API on an older release. Because it
// belongs to the reserved app and exactly matches the current deployment
// Secret, adopt it into managed ownership so a later rotation can retire it.
if _, err := transaction.ExecContext(
ctx,
`UPDATE tb_auth
SET extend = ?, update_time = ?
WHERE app_id = ? AND api_key = ? AND api_secret = ? AND is_delete = 0
AND COALESCE(extend, '') <> ?`,
tenantBootstrapManagedMarker,
now,
credentials.TenantID,
credentials.APIKey,
credentials.Secret,
tenantBootstrapManagedMarker,
); err != nil {
return fmt.Errorf("adopt tenant bootstrap credential failed: %w", err)
}
return nil
}
func rotateTenantBootstrapCredentials(
ctx context.Context,
transaction bootstrapTransaction,
credentials config.TenantBootstrapCredentials,
now string,
) error {
if _, err := transaction.ExecContext(
ctx,
`UPDATE tb_auth
SET is_delete = 1, update_time = ?
WHERE api_key = ? AND api_secret = ?`,
now,
config.LegacyTenantKey,
config.LegacyTenantSecret,View on GitHub (pinned to 5e758547a8)