{"record":{"id":"302e1248f5f24cff","repo":"mastra-ai/mastra","slug":"license-server-responded-with-response-status","errorCode":null,"errorMessage":"License server responded with ${response.status}","messagePattern":"License server responded with (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/core/src/license/index.ts","lineNumber":168,"sourceCode":"    try {\n      if (!this.licenseUrl?.startsWith('https://') && !this.licenseUrl?.includes('localhost')) {\n        this.logger?.warn('License URL is not HTTPS. Proceeding, but this is insecure.');\n      }\n\n      const response = await this.fetchWithRetry(`${this.licenseUrl}/validate`, {\n        method: 'POST',\n        headers: {\n          'content-type': 'application/json',\n        },\n        body: JSON.stringify({ licenseKey: this.licenseKey }),\n      });\n\n      // A 429 or 5xx that survived the retries is a transient server\n      // condition, not a verdict on the license — treat it like an\n      // unreachable server so the lease/grace semantics below apply\n      // instead of invalidating the key.\n      if (response.status === 429 || response.status >= 500) {\n        throw new Error(`License server responded with ${response.status}`);\n      }\n\n      const data = (await response.json()) as LicenseValidationResponse;\n\n      if (data.valid) {\n        this.status = 'valid';\n        this.logger?.info(`License validated${data.expiresAt ? `, expires ${data.expiresAt.slice(0, 10)}` : ''}`);\n        this.cachedResult = data;\n\n        const ttlSeconds = data.leaseTtlSeconds || this.DEFAULT_TTL_MS / 1000;\n        this.cacheExpiry = now + ttlSeconds * 1000;\n        this.gracePeriodEnd = now + this.GRACE_PERIOD_MS;\n\n        this.scheduleRevalidation(ttlSeconds);\n        return true;\n      } else if (data.code === 'RATE_LIMITED') {\n        // Defensive: a throttle marker in the body without a 429 status is\n        // still transient, not a license verdict.","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/license/index.ts#L150-L186","documentation":"During license validation, performValidation retries transient server conditions. If the license server ultimately responds with HTTP 429 or any 5xx after retries are exhausted, it throws 'License server responded with <status>'. The comment in source makes the intent explicit: this is treated like an unreachable server, so lease/grace semantics apply instead of invalidating the key.","triggerScenarios":"License server returns 429 (rate limited) or 5xx (server error) on a validation attempt that survived all retries — network/server outage, license-service deployment, or client exceeding request limits across many processes.","commonSituations":"Mastra license service outage or degraded performance; many CI runners validating one key concurrently; firewall/proxy returning 5xx for the license endpoint; transient cloud incident during app startup.","solutions":["Retry validation after a delay — your app should keep operating under lease/grace while the server is unavailable","Check the license service status page / network path (proxy, firewall, DNS) for the failing 5xx","Reduce concurrent validators: consolidate license checks across processes or use a cached lease","If 429, back off and slow the validation cadence; spread CI jobs' validation attempts"],"exampleFix":"// before\nawait license.performValidation(); // throws on 429/5xx\n// after\ntry {\n  await license.performValidation();\n} catch {\n  // transient server condition — grace lease still applies\n  await new Promise(r => setTimeout(r, 5000));\n  await license.performValidation();\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await licenseClient.validate();\n} catch (e) {\n  const m = /License server responded with (\\d+)/.exec(e.message);\n  if (m && (m[1] === '429' || m[1].startsWith('5'))) {\n    await new Promise(r => setTimeout(r, 2000));\n    await licenseClient.validate(); // grace/lease still applies\n  } else {\n    throw e;\n  }\n}","preventionTips":["Rely on the built-in lease/grace window instead of failing fast on transient statuses","Monitor license-server endpoint availability and proxies","Limit concurrent validators per key across CI runners","Implement exponential backoff around validation calls"],"tags":["license","http-429","http-5xx","transient","retry"],"backgroundTag":"license-server-unreachable","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}