mongodb/node-mongodb-native · error · MongoCryptAzureKMSRequestError

Malformed response body - missing field `expires_in`.

Error message

Malformed response body - missing field `expires_in`.

What it means

Thrown when the Azure IMDS JSON response lacks the expires_in field. The driver uses expires_in to compute the token cache expiry; without it the token cannot be safely cached. MongoCryptAzureKMSRequestError.

Solutions

  1. If testing, ensure the mock IMDS endpoint returns both access_token (string) and expires_in (seconds, number).
  2. If in production Azure, treat this as an Azure platform issue and retry; if persistent, open an Azure support ticket.
  3. Avoid overriding the Azure KMS request URL outside of tests; the default IMDS endpoint returns both fields.
Defensive patterns

Strategy: validation

Validate before calling

function assertAzureTokenShape(body) {
  if (typeof body.access_token !== 'string') throw new Error('missing access_token');
  if (body.expires_in == null) throw new Error('missing expires_in');
  if (Number.isNaN(Number(body.expires_in))) throw new Error('expires_in not numeric');
}

Type guard

function isAzureTokenResponse(b: unknown): b is { access_token: string; expires_in: number } {
  return typeof b === 'object' && b !== null &&
    typeof (b as any).access_token === 'string' &&
    typeof (b as any).expires_in !== 'undefined';
}

Prevention

When it happens

Trigger: An Azure endpoint (or a test/proxy stand-in) returning a JSON body with access_token but omitting expires_in; a custom AzureKMSRequestOptions.url in tests pointing at a mock that returns an incomplete token object.

Common situations: Using a mock/stub IMDS endpoint in CI that returns { access_token } only; Azure regional anomaly returning a truncated body; a man-in-the-middle proxy stripping fields.

Understand the failure class

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/c307436a2e8c6c94. Report an issue: GitHub.

Appendix: source

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

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

  return {
    accessToken: body.access_token,
    expiresOnTimestamp: Date.now() + expiresInMS
  };
}

/**

View on GitHub (pinned to dce7939f86)