{"id":"ef3be7128e9dd93e","repo":"mongodb/node-mongodb-native","slug":"cannot-set-both-proxyoptions-and-kmsconnectcallbac","errorCode":null,"errorMessage":"Cannot set both proxyOptions and kmsConnectCallback","messagePattern":"Cannot set both proxyOptions and kmsConnectCallback","errorType":"validation","errorClass":"MongoCryptInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/client-side-encryption/auto_encrypter.ts","lineNumber":254,"sourceCode":"   *       cryptSharedLibRequired: true\n   *     }\n   *   }\n   * });\n   * ```\n   *\n   * await client.connect();\n   * // From here on, the client will be encrypting / decrypting automatically\n   */\n  constructor(client: MongoClient, options: AutoEncryptionOptions) {\n    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) {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/client-side-encryption/auto_encrypter.ts#L236-L272","documentation":"Thrown by AutoEncrypter constructor (MongoCryptInvalidArgumentError) when both proxyOptions (with a proxyHost) and kmsConnectCallback are supplied in autoEncryption config. The two are alternative mechanisms for routing KMS (Key Management Service) traffic; supplying both is ambiguous so the driver rejects it at construction time.","triggerScenarios":"Configuring MongoClient with autoEncryption.extraOptions or top-level proxyOptions that include proxyHost, AND also setting autoEncryption.kmsConnectCallback.","commonSituations":"Migrating from proxyOptions to kmsConnectCallback without removing the old field; copy-pasting examples that combine both; integrating corporate-proxy support with a custom KMS callback.","solutions":["Choose one KMS transport customization: keep kmsConnectCallback and remove proxyOptions (or vice-versa).","If you need proxying inside a custom callback, implement the proxy logic inside kmsConnectCallback and drop proxyOptions.","Audit the autoEncryption config object for leftover fields from prior setups."],"exampleFix":"// before\nautoEncryption: {\n  kmsProviders: { aws: {} },\n  proxyOptions: { proxyHost: 'corp.proxy', proxyPort: 3128 },\n  kmsConnectCallback: myCb\n}\n\n// after\nautoEncryption: {\n  kmsProviders: { aws: {} },\n  kmsConnectCallback: myCb // handles proxy internally\n}","handlingStrategy":"validation","validationCode":"function validateAutoEncryption(opt) {\n  if (opt.proxyOptions?.proxyHost && opt.kmsConnectCallback)\n    throw new Error('Cannot set both proxyOptions and kmsConnectCallback');\n}","typeGuard":"type KmsTransport = { proxyOptions: { proxyHost: string } } | { kmsConnectCallback: Function };\n// Use a union so only one variant compiles.","tryCatchPattern":"try { new MongoClient(uri, { autoEncryption: opt }); }\ncatch (err) {\n  if (err instanceof MongoCryptInvalidArgumentError && /proxyOptions and kmsConnectCallback/.test(err.message)) {\n    /* drop one option and retry construction */\n  } else throw err;\n}","preventionTips":["Centralize CSFLE options in one builder with a discriminated union.","Code-review config for leftover fields when migrating KMS transport.","Write a unit test asserting the options object does not set both fields."],"tags":["csfle","configuration","kms","proxy"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}