mongodb/node-mongodb-native · error · MongoCryptAzureKMSRequestError
Malformed JSON body in GET request.
Error message
Malformed JSON body in GET request.
What it means
Raised by the Azure KMS credential provider when the HTTP response body from the Azure Instance Metadata Service (IMDS, http://169.254.169.254/...) cannot be parsed as JSON. It is a MongoCryptAzureKMSRequestError thrown in parseResponse after JSON.parse throws. This provider is used by CSFLE/Queryable Encryption to fetch an access token for Azure-managed keys.
Solutions
- Run on an Azure resource with a managed identity enabled (VM, App Service, etc.) so IMDS at 169.254.169.254 returns valid JSON.
- Ensure no HTTP proxy intercepts and rewrites the IMDS response; allowlist 169.254.169.254 if a proxy is mandatory.
- If running locally/off-Azure, supply Azure credentials explicitly via the kmsProviders Azure tenantId/clientId/clientSecret instead of relying on IMDS.
- Verify the IMDS endpoint by curling it directly: curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net' -H 'Metadata: true'.
Example fix
// before: relying on IMDS auto-discovery off-Azure
const client = new MongoClient(uri, {
autoEncryption: { kmsProviders: { azure: {} } } // IMDS path, fails off-Azure
});
// after: explicit Azure service principal credentials
const client = new MongoClient(uri, {
autoEncryption: {
kmsProviders: {
azure: {
tenantId: process.env.AZURE_TENANT_ID,
clientId: process.env.AZURE_CLIENT_ID,
clientSecret: process.env.AZURE_CLIENT_SECRET
}
}
}
}); Defensive patterns
Strategy: fallback
Try / catch
try {
const client = new MongoClient(uri, { autoEncryption: { kmsProviders: { azure: {} } } });
await client.connect();
} catch (e) {
if (e instanceof MongoCryptAzureKMSRequestError && /Malformed JSON/.test(e.message)) {
// fall back to explicit Azure service principal credentials
}
throw e;
} Prevention
- In production prefer explicit azure kmsProvider credentials (tenantId/clientId/clientSecret) over IMDS auto-discovery.
- Allowlist 169.254.169.254 on any egress proxy when relying on managed identity.
When it happens
Trigger: Running CSFLE with an azure KMS provider on a host that cannot reach the Azure IMDS endpoint and returns an HTML/text error page (e.g. a proxy block page); the IMDS endpoint returning a non-JSON 5xx body; network middleware rewriting the response.
Common situations: Running the driver outside an Azure VM/container (no IMDS available, returns connection error or HTML); corporate proxy injecting an authentication/redirect HTML page; Azure IMDS temporarily returning a plain-text error; wrong Azure endpoint configured via test options.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- [Azure KMS]
- Unable to complete request.
- Finalization error
- KMS request timed out
- Malformed response body - missing field `access_token`.
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/4e1c01c0aedf063b.
Report an issue: GitHub.
Appendix: source
Thrown at src/client-side-encryption/providers/azure.ts:75
return fetchAzureKMSToken();
}
}
/** @internal */
export const tokenCache = new AzureCredentialCache();
/** @internal */
async function parseResponse(response: {
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`.'
);
}View on GitHub (pinned to dce7939f86)