{"id":"1572906f81eb898d","repo":"mongodb/node-mongodb-native","slug":"malformed-response-body-missing-field-access-to","errorCode":null,"errorMessage":"Malformed response body - missing field `access_token`.","messagePattern":"Malformed response body - missing field `access_token`\\.","errorType":"exception","errorClass":"MongoCryptAzureKMSRequestError","httpStatus":null,"severity":"error","filePath":"src/client-side-encryption/providers/azure.ts","lineNumber":84,"sourceCode":"  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.'\n    );\n  }\n\n  return {","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/client-side-encryption/providers/azure.ts#L66-L102","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: mock returns { token: '...' }\n// after: mock returns { access_token: '...', expires_in: 3600 }","handlingStrategy":"validation","validationCode":"// Only relevant if you set AzureKMSRequestOptions.url (tests). Validate your mock shape:\nfunction assertTokenResponse(body: unknown): { access_token: string; expires_in: number } {\n  if (typeof body !== 'object' || body === null) throw new Error('not an object');\n  const b = body as Record<string, unknown>;\n  if (typeof b.access_token !== 'string') throw new Error('missing access_token');\n  if (typeof b.expires_in !== 'number') throw new Error('missing expires_in');\n  return b as { access_token: string; expires_in: number };\n}","typeGuard":"function isAccessTokenResponse(body: unknown): body is { access_token: string; expires_in: number } {\n  return typeof (body as any)?.access_token === 'string' && typeof (body as any)?.expires_in === 'number';\n}","tryCatchPattern":null,"preventionTips":["Keep mock token endpoints conformant to the Azure IMDS response schema.","Don't override AzureKMSRequestOptions.url in production."],"tags":["csfle","azure-kms","queryable-encryption"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}