mongodb/node-mongodb-native · error · MongoCryptInvalidArgumentError

Cannot set both proxyOptions and kmsConnectCallback

Error message

Cannot set both proxyOptions and kmsConnectCallback

What it means

Same validation as error 27, but enforced in the ClientEncryption constructor (explicit encryption API). Thrown as MongoCryptInvalidArgumentError when proxyOptions.proxyHost and kmsConnectCallback are both provided. ClientEncryption is used for explicit encryption/decryption rather than auto-encryption, but the KMS routing rule is identical.

Source

Thrown at src/client-side-encryption/client_encryption.ts:132

   *
   * @example
   * ```ts
   * new ClientEncryption(mongoClient, {
   *   keyVaultNamespace: 'client.encryption',
   *   kmsProviders: {
   *     aws: {
   *       accessKeyId: AWS_ACCESS_KEY,
   *       secretAccessKey: AWS_SECRET_KEY
   *     }
   *   }
   * });
   * ```
   */
  constructor(client: MongoClient, options: ClientEncryptionOptions) {
    this._client = client;
    this._proxyOptions = options.proxyOptions ?? {};
    if (this._proxyOptions.proxyHost && options.kmsConnectCallback) {
      throw new MongoCryptInvalidArgumentError(
        'Cannot set both proxyOptions and kmsConnectCallback'
      );
    }
    this._tlsOptions = options.tlsOptions ?? {};
    this._kmsConnectCallback = options.kmsConnectCallback;
    this._kmsProviders = options.kmsProviders || {};
    const { timeoutMS } = resolveTimeoutOptions(client, options);
    this._timeoutMS = timeoutMS;
    this._credentialProviders = options.credentialProviders;

    if (options.credentialProviders?.aws && !isEmptyCredentials('aws', this._kmsProviders)) {
      throw new MongoCryptInvalidArgumentError(
        'Can only provide a custom AWS credential provider when the state machine is configured for automatic AWS credential fetching'
      );
    }

    if (options.keyVaultNamespace == null) {
      throw new MongoCryptInvalidArgumentError('Missing required option `keyVaultNamespace`');

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Remove one of the two options; keep kmsConnectCallback and drop proxyOptions, or vice-versa.
  2. Implement proxy logic inside kmsConnectCallback so only one mechanism is active.
  3. Share a single normalized CSFLE options builder between autoEncryption and ClientEncryption to prevent drift.

Example fix

// before
new ClientEncryption(client, {
  keyVaultNamespace: 'enc.keys',
  kmsProviders: { aws: {} },
  proxyOptions: { proxyHost: 'corp.proxy' },
  kmsConnectCallback: cb
});

// after
new ClientEncryption(client, {
  keyVaultNamespace: 'enc.keys',
  kmsProviders: { aws: {} },
  kmsConnectCallback: cb
});
Defensive patterns

Strategy: validation

Validate before calling

function validateClientEncryption(opt) {
  if (opt.proxyOptions?.proxyHost && opt.kmsConnectCallback)
    throw new Error('Cannot set both proxyOptions and kmsConnectCallback');
}

Type guard

type ClientEncKmsTransport = { proxyOptions: { proxyHost: string } } | { kmsConnectCallback: Function };

Try / catch

try { new ClientEncryption(client, opt); }
catch (err) {
  if (err instanceof MongoCryptInvalidArgumentError && /proxyOptions and kmsConnectCallback/.test(err.message)) {
    /* drop one field */
  } else throw err;
}

Prevention

When it happens

Trigger: Constructing `new ClientEncryption(client, { proxyOptions: { proxyHost }, kmsConnectCallback })` for explicit encryption workflows.

Common situations: Building a ClientEncryption for explicit encrypt/decrypt while reusing an autoEncryption-style config that included both fields; corporate proxy setups combined with custom KMS hooks.

Related errors


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