mastra-ai/mastra · warning
License server rate limited: ${data.reason}
Error message
License server rate limited: ${data.reason} What it means
If the license validation response body carries code 'RATE_LIMITED' without an HTTP 429 status, performValidation throws 'License server rate limited: <reason>'. The source comment marks this as defensive: a throttle marker in the body is still a transient condition, not a verdict on the license, so it throws rather than marking the key invalid (which is what happens for INVALID_KEY/EXPIRED/REVOKED).
Source
Thrown at packages/core/src/license/index.ts:187
}
const data = (await response.json()) as LicenseValidationResponse;
if (data.valid) {
this.status = 'valid';
this.logger?.info(`License validated${data.expiresAt ? `, expires ${data.expiresAt.slice(0, 10)}` : ''}`);
this.cachedResult = data;
const ttlSeconds = data.leaseTtlSeconds || this.DEFAULT_TTL_MS / 1000;
this.cacheExpiry = now + ttlSeconds * 1000;
this.gracePeriodEnd = now + this.GRACE_PERIOD_MS;
this.scheduleRevalidation(ttlSeconds);
return true;
} else if (data.code === 'RATE_LIMITED') {
// Defensive: a throttle marker in the body without a 429 status is
// still transient, not a license verdict.
throw new Error(`License server rate limited: ${data.reason}`);
} else {
this.status = 'invalid';
this.logger?.error(`License validation failed: ${data.code} - ${data.reason}`);
this.clearCache();
return false;
}
} catch {
// Network error or server unreachable
if (this.cachedResult && now < this.gracePeriodEnd) {
this.logger?.warn('License server unreachable. Using cached license (within grace period).');
this.status = 'valid';
this.scheduleRevalidation(this.DEFAULT_TTL_MS / 1000); // Retry later
return true;
} else if (this.cachedResult) {
this.logger?.error('License server unreachable and grace period expired. Disabling enterprise features.');
this.status = 'invalid';
this.clearCache();
return false;View on GitHub (pinned to 75dd419e61)
Solutions
- Back off and retry — RATE_LIMITED is transient; the key itself is fine
- Reduce validation frequency: cache the lease for the full leaseTtlSeconds and avoid tight revalidation loops
- Consolidate license checks: run one validator per host/pod and share the result internally
- Inspect proxies/gateways between client and license server that may mangle HTTP status codes
Example fix
// before
while (true) { await license.performValidation(); } // hammers server -> RATE_LIMITED
// after
try {
await license.performValidation();
} catch (e) {
if (String(e).includes('rate limited')) {
await new Promise(r => setTimeout(r, 30_000)); // back off, then retry
await license.performValidation();
}
} Defensive patterns
Strategy: retry
Try / catch
try {
await licenseClient.validate();
} catch (e) {
if (e.message.startsWith('License server rate limited')) {
await new Promise(r => setTimeout(r, 30_000)); // exponential backoff
await licenseClient.validate();
} else {
throw e;
}
} Prevention
- Cache validation results for the full leaseTtlSeconds
- Avoid tight revalidation loops in fleets of workers
- One validator per host/pod; share the verdict internally
- Check for gateways/proxies that rewrite HTTP statuses to 200
When it happens
Trigger: The license server responds 200 (or another non-429 status) but the JSON body contains valid:false, code:'RATE_LIMITED' — an inconsistent server response or intermediary stripping/rewriting status codes — while the client is exceeding validation request limits.
Common situations: A reverse proxy or API gateway collapsing error statuses into 200 responses; many processes/containers validating the same key concurrently and hitting server-side throttling; aggressive revalidation loops in a fleet of workers.
Related errors
- License server responded with ${response.status}
- Failed to check whether Slack app exists: ${data.error ?? 'u
- Telegram ${method} failed: ${detail}
- request failed with status ${response.status}: ${responseTex
- Failed to list repos (${res.status})
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/dfc7fd179f029193.
Report an issue: GitHub.