mastra-ai/mastra · error · MastraError
AZURE_AD_TOKEN_ERROR
AZURE_AD_TOKEN_ERROR
Error message
Failed to get Azure AD token: ${response.status} ${error} What it means
The gateway's OAuth client-credentials request to the Azure AD (Entra ID) token endpoint returned a non-OK HTTP response; the gateway wraps the status and response body in AZURE_AD_TOKEN_ERROR. This happens inside getAzureADToken, called by the token accessor, when Microsoft's identity platform rejects the token request.
Source
Thrown at packages/core/src/llm/model/gateways/azure.ts:391
const body = new URLSearchParams({
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
scope: 'https://management.azure.com/.default',
});
const response = await fetch(tokenEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: body.toString(),
});
if (!response.ok) {
const error = await response.text();
throw new MastraError({
id: 'AZURE_AD_TOKEN_ERROR',
domain: 'LLM',
category: 'UNKNOWN',
text: `Failed to get Azure AD token: ${response.status} ${error}`,
});
}
const tokenResponse = (await response.json()) as AzureTokenResponse;
const expiresAt = Math.floor(Date.now() / 1000) + tokenResponse.expires_in;
await this.tokenCache.set(cacheKey, {
token: tokenResponse.access_token,
expiresAt,
});
return tokenResponse.access_token;
}View on GitHub (pinned to 75dd419e61)
Solutions
- Verify tenantId, clientId, and clientSecret are correct and current (App Registration > Certificates & secrets in the Azure portal).
- Read the AADSTS error code in the message body — it names the exact cause (e.g. AADSTS7000215 invalid client secret).
- Confirm the app registration exists in the specified tenant and the secret has not expired; create a new secret if needed.
- Check network/proxy access to login.microsoftonline.com from the runtime environment.
- Ensure the requested scope (e.g. https://cognitiveservices.azure.com/.default) is granted admin consent.
Example fix
// before (stale secret) clientSecret: process.env.AZURE_CLIENT_SECRET // old value after rotation -> 401 invalid_client // after clientSecret: process.env.AZURE_CLIENT_SECRET // rotated value copied fresh from Certificates & secrets, trimmed
Defensive patterns
Strategy: try-catch
Validate before calling
function assertAdCredentials(env: Record<string,string|undefined>) {
for (const k of ['AZURE_TENANT_ID','AZURE_CLIENT_ID','AZURE_CLIENT_SECRET']) {
if (!env[k]?.trim()) throw new Error(`${k} is not set — AD token request would fail`);
}
}
assertAdCredentials(process.env); Try / catch
try {
const token = await gateway.token();
} catch (e) {
if (e instanceof MastraError && e.id === 'AZURE_AD_TOKEN_ERROR') {
const aadsts = /AADSTS\d+/.exec(e.message)?.[0];
console.error(`Azure AD token request failed (${aadsts ?? 'unknown'}); check tenantId/clientId/clientSecret and network access to login.microsoftonline.com`);
return null; // or fall back to apiKey auth
}
throw e;
} Prevention
- Rotate client secrets on a schedule and update the secret store before expiry.
- Trim whitespace/quotes when copying client secrets into env vars.
- Verify outbound network access to login.microsoftonline.com from deployment environments (allowlist via proxies).
- Watch for the AADSTS code in the error body — each code maps to a specific fixable cause (expired secret, wrong tenant, missing consent).
When it happens
Trigger: POST to https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token fails — e.g. 401 invalid_client (wrong clientId/secret), 400 invalid_request (bad tenantId or malformed body), 400 AADSTS700016 (app not found in tenant), or a proxy returning 403/502.
Common situations: Expired or rotated client secrets still referenced in env; client secret copied with whitespace/quotes; tenantId from a tenant where the app registration does not exist; corporate proxy blocking login.microsoftonline.com; requested scope not granted admin consent.
Related errors
- AZURE_ENTRA_ID_AUTH_NOT_CONFIGURED
- AZURE_ENTRA_ID_TOKEN_ERROR
- Slack OAuth HTTP error: ${tokenResponse.status} ${tokenRespo
- GitHub OAuth token exchange failed: ${res.status}
- GitHub OAuth token exchange returned no token: ${data.error_
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/8d51c1ea55ba844e.
Report an issue: GitHub.