mongodb/node-mongodb-native · error · MongoCryptAzureKMSRequestError

Unable to complete request.

Error message

Unable to complete request.

What it means

Thrown by the Azure IMDS token parser when the HTTP response status is not 200. The response parsed as JSON but the endpoint signaled failure (e.g. 400/401/403/500). The parsed body is attached to the error so callers can inspect the Azure error code/message. This indicates the IMDS endpoint understood the request but refused to issue a token.

Source

Thrown at src/client-side-encryption/providers/azure.ts:80

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`.'
    );
  }

  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.'

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Inspect error.cause / the attached body for the Azure-specific error code and message.
  2. Confirm a managed identity is attached to the VM in the Azure portal (System assigned or User assigned).
  3. If using client_id (username), verify that user-assigned identity still exists and is attached.
  4. Retry after transient errors; for 4xx verify IAM/Key Vault access policy grants the identity the 'key/wrap/unwrap' permissions on the CMK.
  5. Fall back to explicit azure KMS provider credentials (tenantId/clientId/clientSecret) if IMDS is unavailable.

Example fix

// before: relying on IMDS with no identity on the VM
const kmsProviders = await client.autoEncryption?.getKmsProviders?.();

// after: attach a managed identity in Azure, or pass explicit creds
const kmsProviders = {
  azure: { tenantId: '<tenant>', clientId: '<app>', clientSecret: '<secret>' }
};
Defensive patterns

Strategy: try-catch

Type guard

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

Try / catch

try {
  await client.connect();
} catch (err) {
  if (err instanceof MongoCryptAzureKMSRequestError && err.message === 'Unable to complete request.') {
    console.error('Azure IMDS refused token request; check managed identity:', err);
  }
}

Prevention

When it happens

Trigger: Raised in parseResponse() after a successful JSON.parse when status !== 200; reachable whenever fetchAzureKMSToken() gets a non-OK response from the IMDS endpoint.

Common situations: VM has no managed identity assigned (400/missing identity); the requested resource audience is wrong; Azure IMDS throttling or transient platform error; the client_id query param refers to a deleted user-assigned identity; IMDS token service is temporarily unavailable.

Related errors


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