{"id":"edab17b85107ebfb","repo":"mongodb/node-mongodb-native","slug":"can-only-provide-a-custom-aws-credential-provider","errorCode":null,"errorMessage":"Can only provide a custom AWS credential provider when the state machine is configured for automatic AWS credential fetching","messagePattern":"Can only provide a custom AWS credential provider when the state machine is configured for automatic AWS credential fetching","errorType":"validation","errorClass":"MongoCryptInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/client-side-encryption/auto_encrypter.ts","lineNumber":264,"sourceCode":"    this._client = client;\n    this._bypassEncryption = options.bypassAutoEncryption === true;\n\n    this._keyVaultNamespace = options.keyVaultNamespace || 'admin.datakeys';\n    this._keyVaultClient = options.keyVaultClient || client;\n    this._metaDataClient = options.metadataClient || client;\n    this._proxyOptions = options.proxyOptions || {};\n    if (this._proxyOptions.proxyHost && options.kmsConnectCallback) {\n      throw new MongoCryptInvalidArgumentError(\n        'Cannot set both proxyOptions and kmsConnectCallback'\n      );\n    }\n    this._tlsOptions = options.tlsOptions || {};\n    this._kmsConnectCallback = options.kmsConnectCallback;\n    this._kmsProviders = options.kmsProviders || {};\n    this._credentialProviders = options.credentialProviders;\n\n    if (options.credentialProviders?.aws && !isEmptyCredentials('aws', this._kmsProviders)) {\n      throw new MongoCryptInvalidArgumentError(\n        'Can only provide a custom AWS credential provider when the state machine is configured for automatic AWS credential fetching'\n      );\n    }\n\n    const mongoCryptOptions: MongoCryptOptions = {\n      errorWrapper: defaultErrorWrapper\n    };\n    if (options.schemaMap) {\n      if (ByteUtils.isUint8Array(options.schemaMap)) {\n        mongoCryptOptions.schemaMap = options.schemaMap;\n      } else {\n        mongoCryptOptions.schemaMap = serialize(options.schemaMap);\n      }\n    }\n\n    if (options.encryptedFieldsMap) {\n      if (ByteUtils.isUint8Array(options.encryptedFieldsMap)) {\n        mongoCryptOptions.encryptedFieldsMap = options.encryptedFieldsMap;","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/client-side-encryption/auto_encrypter.ts#L246-L282","documentation":"Thrown by AutoEncrypter constructor (MongoCryptInvalidArgumentError) when credentialProviders.aws is set AND kmsProviders.aws is not empty. The custom AWS credential provider callback is only valid when the state machine is configured for automatic AWS credential fetching, i.e. when kmsProviders.aws is absent/empty so the driver knows to call the provider.","triggerScenarios":"Providing both autoEncryption.kmsProviders.aws = { accessKeyId, secretAccessKey } and autoEncryption.credentialProviders.aws = asyncProvider at the same time.","commonSituations":"Static credentials in config plus a rotation/refresh callback; transitioning from static creds to dynamic fetching without clearing kmsProviders.aws; copy-pasting examples that include both.","solutions":["If you want the callback to supply AWS credentials, set kmsProviders.aws = {} (empty) so isEmptyCredentials returns true.","If you want static credentials, remove credentialProviders.aws.","Use isEmptyCredentials('aws', kmsProviders) in your own config builder to verify the combination before constructing the client."],"exampleFix":"// before\nautoEncryption: {\n  kmsProviders: { aws: { accessKeyId, secretAccessKey } },\n  credentialProviders: { aws: awsProvider }\n}\n\n// after\nautoEncryption: {\n  kmsProviders: { aws: {} },\n  credentialProviders: { aws: awsProvider }\n}","handlingStrategy":"validation","validationCode":"function validateAwsProvider(opt) {\n  const awsEmpty = opt.kmsProviders?.aws == null || Object.keys(opt.kmsProviders.aws).length === 0;\n  if (opt.credentialProviders?.aws && !awsEmpty)\n    throw new Error('Remove kmsProviders.aws when using credentialProviders.aws');\n}","typeGuard":"type AwsCreds =\n  | { kmsProviders: { aws: Record<string, never> }; credentialProviders: { aws: () => Promise<any> } }\n  | { kmsProviders: { aws: { accessKeyId: string; secretAccessKey: string } }; credentialProviders?: undefined };","tryCatchPattern":"try { new MongoClient(uri, { autoEncryption: opt }); }\ncatch (err) {\n  if (err instanceof MongoCryptInvalidArgumentError && /automatic AWS credential fetching/.test(err.message)) {\n    /* set kmsProviders.aws = {} and retry */\n  } else throw err;\n}","preventionTips":["When introducing credentialProviders.aws, blank out kmsProviders.aws.","Use isEmptyCredentials('aws', kmsProviders) as a config sanity check.","Document which CSFLE credentialing style each environment uses."],"tags":["csfle","configuration","kms","aws","credentials"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}