mongodb/node-mongodb-native · error · MongoCryptAzureKMSRequestError
Malformed response body - missing field `access_token`.
Error message
Malformed response body - missing field `access_token`.
What it means
Thrown when the Azure IMDS returned HTTP 200 and parseable JSON, but the JSON object has no access_token field. The Azure token contract requires access_token; its absence means the response shape is non-conformant. Typically indicates a malformed mock/proxy response or an unexpected IMDS API version mismatch.
Source
Thrown at src/client-side-encryption/providers/azure.ts:84
body: string;
status?: number;
}): Promise<AzureTokenCacheEntry> {
const { status, body: rawBody } = response;
const body: { expires_in?: number; access_token?: string } = (() => {
try {
return JSON.parse(rawBody);
} catch {
throw new MongoCryptAzureKMSRequestError('Malformed JSON body in GET request.');
}
})();
if (status !== 200) {
throw new MongoCryptAzureKMSRequestError('Unable to complete request.', body);
}
if (!body.access_token) {
throw new MongoCryptAzureKMSRequestError(
'Malformed response body - missing field `access_token`.'
);
}
if (!body.expires_in) {
throw new MongoCryptAzureKMSRequestError(
'Malformed response body - missing field `expires_in`.'
);
}
const expiresInMS = Number(body.expires_in) * 1000;
if (Number.isNaN(expiresInMS)) {
throw new MongoCryptAzureKMSRequestError(
'Malformed response body - unable to parse int from `expires_in` field.'
);
}
return {View on GitHub (pinned to 3366c21a63)
Solutions
- If using a custom url in AzureKMSRequestOptions (tests), ensure the mock returns { access_token, expires_in }.
- Ensure no intermediary rewrites the IMDS response.
- Verify the request includes 'Metadata: true' header and the correct api-version=2018-02-01.
- Fall back to explicit azure KMS provider credentials.
Example fix
// before: mock returns { token: '...' }
// after: mock returns { access_token: '...', expires_in: 3600 } Defensive patterns
Strategy: validation
Validate before calling
// Only relevant if you set AzureKMSRequestOptions.url (tests). Validate your mock shape:
function assertTokenResponse(body: unknown): { access_token: string; expires_in: number } {
if (typeof body !== 'object' || body === null) throw new Error('not an object');
const b = body as Record<string, unknown>;
if (typeof b.access_token !== 'string') throw new Error('missing access_token');
if (typeof b.expires_in !== 'number') throw new Error('missing expires_in');
return b as { access_token: string; expires_in: number };
} Type guard
function isAccessTokenResponse(body: unknown): body is { access_token: string; expires_in: number } {
return typeof (body as any)?.access_token === 'string' && typeof (body as any)?.expires_in === 'number';
} Prevention
- Keep mock token endpoints conformant to the Azure IMDS response schema.
- Don't override AzureKMSRequestOptions.url in production.
When it happens
Trigger: In parseResponse() when status === 200 but body.access_token is falsy; seen with custom url/headers test overrides, or when an intermediary returns a 200 JSON body of a different shape.
Common situations: Using AzureKMSRequestOptions.url to point at a mock server whose response omits access_token; api-version query param drift; an API gateway rewriting the response; using a non-Azure metadata service that returns 200 JSON.
Related errors
- Malformed JSON body in GET request.
- Unable to complete request.
- Malformed response body - missing field `expires_in`.
- Malformed response body - unable to parse int from `expires_
- [Azure KMS] ${error.message}
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/1572906f81eb898d.json.
Report an issue: GitHub.