mongodb/node-mongodb-native · critical · MongoRuntimeError

Expected result of decryption to be deserialized BSON object

Error message

Expected result of decryption to be deserialized BSON object

What it means

Thrown by decorateDecryptionResult() when, after libmongocrypt returns a decrypted response, that response is still a raw Uint8Array instead of a deserialized BSON object. decorateDecryptionResult walks the decrypted object to mark fields that were encrypted, so it requires an object, not bytes. Hitting this means the CSFLE/Queryable-Encryption decryption pipeline returned bytes where the driver expected an object, typically indicating a version mismatch or a bug in the encryption bindings. It surfaces as a MongoRuntimeError from connection.ts and wire_protocol/responses.ts.

Source

Thrown at src/utils.ts:1358

 * Recurse through the (identically-shaped) `decrypted` and `original`
 * objects and attach a `decryptedKeys` property on each sub-object that
 * contained encrypted fields. Because we only call this on BSON responses,
 * we do not need to worry about circular references.
 *
 * @internal
 */
export function decorateDecryptionResult(
  decrypted: Document & { [kDecoratedKeys]?: Array<string> },
  original: Document,
  isTopLevelDecorateCall = true
): void {
  if (isTopLevelDecorateCall) {
    // The original value could have been either a JS object or a BSON buffer
    if (ByteUtils.isUint8Array(original)) {
      original = deserialize(original);
    }
    if (ByteUtils.isUint8Array(decrypted)) {
      throw new MongoRuntimeError('Expected result of decryption to be deserialized BSON object');
    }
  }

  if (!decrypted || typeof decrypted !== 'object') return;
  for (const k of Object.keys(decrypted)) {
    const originalValue = original[k];

    // An object was decrypted by libmongocrypt if and only if it was
    // a BSON Binary object with subtype 6.
    if (originalValue && originalValue._bsontype === 'Binary' && originalValue.sub_type === 6) {
      if (!decrypted[kDecoratedKeys]) {
        Object.defineProperty(decrypted, kDecoratedKeys, {
          value: [],
          configurable: true,
          enumerable: false,
          writable: false
        });
      }

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Align versions: use the mongodb-client-encryption (and mongocryptd / crypt_shared) version documented as compatible with your mongodb driver version.
  2. Rebuild native dependencies (npm rebuild / reinstall) so the libmongocrypt binding compiles and loads correctly.
  3. Point to a compatible crypt_shared library via the cryptSharedLibPath option, or remove it to use mongocryptd.
  4. If the issue persists on matched, freshly-built versions, capture the driver + encryption library versions and file a driver bug with the schema and a minimal repro.

Example fix

// before: driver and encryption lib mismatched
const client = new MongoClient(uri, { autoEncryption: { ... } }); // => MongoRuntimeError on first query

// after: pin compatible versions in package.json
// "mongodb": "^6.5.0",
// "mongodb-client-encryption": "^6.0.0"
// then: rm -rf node_modules && npm install
Defensive patterns

Strategy: try-catch

Validate before calling

import { MongoClient } from 'mongodb';
function assertEncryptionCompat(driverVer: string, encVer: string): void {
  // enforce a known-good combination per the driver's compatibility matrix
  const ok = driverVer.startsWith('6.') && encVer.startsWith('6.');
  if (!ok) throw new Error(`Unsupported driver/encryption combo: mongodb ${driverVer} + mongodb-client-encryption ${encVer}`);
}

Try / catch

try {
  await encryptedCollection.findOne(filter);
} catch (err) {
  if (err instanceof MongoRuntimeError && /Expected result of decryption to be deserialized BSON/.test(err.message)) {
    throw new Error('CSFLE decryption pipeline mismatch; align mongodb and mongodb-client-encryption versions and rebuild natives', { cause: err });
  }
  throw err;
}

Prevention

When it happens

Trigger: Running Client-Side Field Level Encryption (CSFLE) or Queryable Encryption where the installed mongodb-client-encryption native binding is incompatible with the driver version; a custom crypt shared library returning an unexpected shape; an internal regression in the decrypt->deserialize ordering.

Common situations: Upgrading the driver without upgrading mongodb-client-encryption (or vice versa); a broken/incomplete native build of libmongocrypt; mismatched crypt_shared library version; environment where the native addon failed to load and fell back to a code path that returns bytes.

Related errors


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