mongodb/node-mongodb-native · error · MongoCryptInvalidArgumentError

Can only provide a custom AWS credential provider when the…

Error message

Can only provide a custom AWS credential provider when the state machine is configured for automatic AWS credential fetching

What it means

Thrown by the ClientEncryption constructor when credentialProviders.aws is defined but kmsProviders.aws contains non-empty static credentials. When using a custom AWS credential provider for dynamic credential fetching, kmsProviders.aws must be an empty object {} to indicate that credentials should be loaded dynamically. Providing both is a configuration conflict. This is a MongoCryptInvalidArgumentError.

Solutions

  1. Set kmsProviders.aws to {} when using credentialProviders.aws for dynamic fetching
  2. Remove credentialProviders.aws if you intend to use static credentials in kmsProviders.aws

Example fix

// before
new ClientEncryption(client, {
  keyVaultNamespace: 'encryption.__keyVault',
  kmsProviders: { aws: { accessKeyId: 'AKIA...', secretAccessKey: '...' } },
  credentialProviders: { aws: myAwsProvider }
});

// after (dynamic fetching)
new ClientEncryption(client, {
  keyVaultNamespace: 'encryption.__keyVault',
  kmsProviders: { aws: {} },
  credentialProviders: { aws: myAwsProvider }
});
Defensive patterns

Strategy: validation

Validate before calling

// Before creating ClientEncryption
const { kmsProviders, credentialProviders } = options;
if (credentialProviders?.aws && kmsProviders?.aws && Object.keys(kmsProviders.aws).length > 0) {
  throw new Error('Set kmsProviders.aws to {} when using credentialProviders.aws');
}

Prevention

When it happens

Trigger: Constructing new ClientEncryption with both kmsProviders: { aws: { accessKeyId: '...', secretAccessKey: '...' } } and credentialProviders: { aws: fn }. The constructor rejects this before creating the MongoCrypt context.

Common situations: Transitioning from static AWS keys to IAM role-based credential fetching without clearing the old kmsProviders.aws values; configuration templates that pre-populate kmsProviders and code that adds credentialProviders at runtime; environment variables injecting static credentials that conflict with code-level dynamic providers.

Related errors


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

Appendix: source

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

   * ```
   */
  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`');
    }

    const mongoCryptOptions: MongoCryptOptions = {
      ...options,
      kmsProviders: serialize(this._kmsProviders),
      errorWrapper: defaultErrorWrapper
    };

    this._keyVaultNamespace = options.keyVaultNamespace;
    this._keyVaultClient = options.keyVaultClient || client;
    const MongoCrypt = ClientEncryption.getMongoCrypt();
    this._mongoCrypt = new MongoCrypt(mongoCryptOptions);

View on GitHub (pinned to dce7939f86)