{"id":"12fc5d1f45d62f4d","repo":"mongodb/node-mongodb-native","slug":"unable-to-complete-request","errorCode":null,"errorMessage":"Unable to complete request.","messagePattern":"Unable to complete request\\.","errorType":"exception","errorClass":"MongoCryptAzureKMSRequestError","httpStatus":null,"severity":"error","filePath":"src/client-side-encryption/providers/azure.ts","lineNumber":80,"sourceCode":"export const tokenCache = new AzureCredentialCache();\n\n/** @internal */\nasync function parseResponse(response: {\n  body: string;\n  status?: number;\n}): Promise<AzureTokenCacheEntry> {\n  const { status, body: rawBody } = response;\n\n  const body: { expires_in?: number; access_token?: string } = (() => {\n    try {\n      return JSON.parse(rawBody);\n    } catch {\n      throw new MongoCryptAzureKMSRequestError('Malformed JSON body in GET request.');\n    }\n  })();\n\n  if (status !== 200) {\n    throw new MongoCryptAzureKMSRequestError('Unable to complete request.', body);\n  }\n\n  if (!body.access_token) {\n    throw new MongoCryptAzureKMSRequestError(\n      'Malformed response body - missing field `access_token`.'\n    );\n  }\n\n  if (!body.expires_in) {\n    throw new MongoCryptAzureKMSRequestError(\n      'Malformed response body - missing field `expires_in`.'\n    );\n  }\n\n  const expiresInMS = Number(body.expires_in) * 1000;\n  if (Number.isNaN(expiresInMS)) {\n    throw new MongoCryptAzureKMSRequestError(\n      'Malformed response body - unable to parse int from `expires_in` field.'","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/client-side-encryption/providers/azure.ts#L62-L98","documentation":"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.","triggerScenarios":"Raised in parseResponse() after a successful JSON.parse when status !== 200; reachable whenever fetchAzureKMSToken() gets a non-OK response from the IMDS endpoint.","commonSituations":"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.","solutions":["Inspect error.cause / the attached body for the Azure-specific error code and message.","Confirm a managed identity is attached to the VM in the Azure portal (System assigned or User assigned).","If using client_id (username), verify that user-assigned identity still exists and is attached.","Retry after transient errors; for 4xx verify IAM/Key Vault access policy grants the identity the 'key/wrap/unwrap' permissions on the CMK.","Fall back to explicit azure KMS provider credentials (tenantId/clientId/clientSecret) if IMDS is unavailable."],"exampleFix":"// before: relying on IMDS with no identity on the VM\nconst kmsProviders = await client.autoEncryption?.getKmsProviders?.();\n\n// after: attach a managed identity in Azure, or pass explicit creds\nconst kmsProviders = {\n  azure: { tenantId: '<tenant>', clientId: '<app>', clientSecret: '<secret>' }\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { MongoCryptAzureKMSRequestError } from 'mongodb';\nfunction isAzureKMSRequestError(e: unknown): e is MongoCryptAzureKMSRequestError {\n  return e instanceof MongoCryptAzureKMSRequestError;\n}","tryCatchPattern":"try {\n  await client.connect();\n} catch (err) {\n  if (err instanceof MongoCryptAzureKMSRequestError && err.message === 'Unable to complete request.') {\n    console.error('Azure IMDS refused token request; check managed identity:', err);\n  }\n}","preventionTips":["Attach a managed identity to the Azure VM before deploying CSFLE.","Grant the identity key/wrapKey/unwrapKey on the Key Vault CMK via access policy or RBAC.","Instrument the CSFLE startup path to surface the IMDS error body."],"tags":["csfle","azure-kms","auth","queryable-encryption"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}