mongodb/node-mongodb-native · error · MongoCryptAzureKMSRequestError

Malformed JSON body in GET request.

Error message

Malformed JSON body in GET request.

What it means

Thrown by the CSFLE Azure KMS credential provider when the HTTP response body from the Azure Instance Metadata Service (IMDS) endpoint (169.254.169.254) cannot be parsed as JSON. The driver calls this endpoint to fetch an access token for Azure Key Vault when automatic KMS credentials are used. A non-JSON body indicates the endpoint returned HTML (e.g. a proxy error page), an empty body, or otherwise corrupt content.

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 3366c21a63)

Solutions

  1. If not running on an Azure VM, supply explicit Azure KMS credentials in the KMS providers map instead of relying on IMDS auto-detection.
  2. Verify the host can reach 169.254.169.254: curl -H 'Metadata: true' 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net'
  3. Disable or bypass any HTTP proxy for the link-local IP 169.254.169.254.
  4. Check that a system-assigned or user-assigned managed identity is enabled on the Azure VM.

Example fix

// before
const client = new MongoClient(uri, {
  autoEncryption: { keyVaultNamespace: 'encryption.__dataKeys', kmsProviders: {} }
});

// after (explicit credentials when not on Azure VM)
const kmsProviders = { azure: { tenantId, clientId, clientSecret } };
const client = new MongoClient(uri, {
  autoEncryption: { keyVaultNamespace: 'encryption.__dataKeys', kmsProviders }
});
Defensive patterns

Strategy: try-catch

Validate before calling

// Before constructing the AutoEncryption client, decide whether IMDS is reachable.
async function canReachAzureIMDS(): Promise<boolean> {
  try {
    const controller = new AbortController();
    const t = setTimeout(() => controller.abort(), 2000);
    const res = await fetch(
      'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net',
      { headers: { Metadata: 'true' }, signal: controller.signal }
    );
    clearTimeout(t);
    if (!res.ok) return false;
    await res.json(); // throws if not JSON
    return true;
  } catch {
    return false;
  }
}
const kmsProviders = (await canReachAzureIMDS()) ? {} : { azure: { tenantId, clientId, clientSecret } };

Type guard

import { MongoCryptAzureKMSRequestError } from 'mongodb';
function isAzureKMSError(e: unknown): e is MongoCryptAzureKMSRequestError {
  return e instanceof MongoCryptAzureKMSRequestError;
}

Try / catch

try {
  const client = new MongoClient(uri, { autoEncryption: { kmsProviders, keyVaultNamespace } });
  await client.connect();
} catch (err) {
  if (err instanceof MongoCryptAzureKMSRequestError && /Malformed JSON/.test(err.message)) {
    // IMDS not reachable; supply explicit azure credentials and retry.
  }
  throw err;
}

Prevention

When it happens

Trigger: Triggered inside parseResponse() when JSON.parse(rawBody) throws, which is called from fetchAzureKMSToken() during CSFLE/AutoEncryption startup or token refresh when no explicit azure KMS provider credentials were supplied.

Common situations: Running CSFLE on a machine that is NOT an Azure VM (so 169.254.169.254 returns nothing or a captive-portal HTML page); corporate HTTP proxy intercepting the link-local address and returning HTML; network policy blocking the IMDS endpoint and returning an error page; attempting local development of CSFLE without providing explicit azure credentials.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/4e1c01c0aedf063b.json. Report an issue: GitHub.