iflytek/astron-agent · error
check tenant bootstrap managed credential failed
Error message
check tenant bootstrap managed credential failed: %w
What it means
findTenantBootstrapCredential wraps a database error that occurred while querying tb_auth for a managed (tenant-bootstrap-marked) credential row during tenant bootstrap reconciliation. The %w wrapper means an underlying MySQL/driver error was returned by QueryRowContext/Scan and it is not sql.ErrNoRows. It signals infrastructure failure of the credential-collision check, not a credential conflict.
Solutions
- Check tenant service logs for the wrapped underlying driver error (%v of the cause) to identify the exact MySQL failure.
- Verify MySQL connectivity, credentials, and that the tenant service can reach the DB host/port.
- Confirm schema migrations for tb_auth (including extend and is_delete columns) have been applied.
- If lock-wait timeouts appear, reduce concurrency of bootstrap reconciliation or raise innodb_lock_wait_timeout.
- Retry the reconciliation once connectivity is restored; the operation is transactional and safe to re-run.
Example fix
// before: no health check before reconcile
reconcileTenantBootstrapTransaction(ctx, db, cfg)
// after: verify DB reachable first
if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("database unavailable, skipping reconcile: %w", err)
}
return reconcileTenantBootstrapTransaction(ctx, db, cfg) Defensive patterns
Strategy: retry
Validate before calling
if err := db.PingContext(ctx); err != nil { return fmt.Errorf("db not reachable before bootstrap reconcile: %w", err) } Try / catch
err := reconcileTenantBootstrapTransaction(ctx, tx, cfg)
var retryable *mysql.MySQLError
if errors.As(err, &retryable) && isTransientCode(retryable.Number) {
// retry with backoff
} Prevention
- Run schema migrations before starting tenant bootstrap.
- Grant the service account SELECT/UPDATE on tb_auth.
- Monitor MySQL connectivity and lock-wait metrics.
- Serialize bootstrap reconciliation runs with a lock.
When it happens
Trigger: The second QueryRowContext inside findTenantBootstrapCredential (SELECT api_secret, is_delete FROM tb_auth WHERE app_id=? AND api_key=? AND COALESCE(extend,'')<>? ... FOR UPDATE) fails with any error other than sql.ErrNoRows, e.g. connection drop, lock wait timeout, table missing, or permissions error, while reconcileTenantBootstrapTransaction runs inside its DB transaction.
Common situations: MySQL is restarting or unreachable mid-transaction; the FOR UPDATE row lock times out under contention from concurrent bootstrap reconcilers; migrations were not applied so tb_auth or the extend column does not exist; the DB user lacks SELECT privilege on tb_auth.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- adopt tenant bootstrap 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/930ef3e0642125cd.
Report an issue: GitHub.
Appendix: source
Thrown at core/tenant/tools/database/bootstrap_credentials.go:201
err = transaction.QueryRowContext(
ctx,
`SELECT api_secret, is_delete
FROM tb_auth
WHERE app_id = ? AND api_key = ? AND COALESCE(extend, '') <> ?
LIMIT 1 FOR UPDATE`,
credentials.TenantID,
credentials.APIKey,
tenantBootstrapManagedMarker,
).Scan(&unmanagedSecret, &unmanagedIsDelete)
if err == nil {
if !unmanagedSecret.Valid || !unmanagedIsDelete.Valid || unmanagedIsDelete.Bool ||
subtle.ConstantTimeCompare([]byte(unmanagedSecret.String), []byte(credentials.Secret)) != 1 {
return false, errors.New("tenant bootstrap API key conflicts with an unmanaged credential")
}
return true, nil
}
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return false, fmt.Errorf("check tenant bootstrap managed credential failed: %w", err)
}
return false, nil
}
func adoptTenantBootstrapCredential(
ctx context.Context,
transaction bootstrapTransaction,
credentials config.TenantBootstrapCredentials,
now string,
) 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 = ?View on GitHub (pinned to 5e758547a8)