{"record":{"id":"b6ed4345bbd14938","repo":"mongodb/node-mongodb-native","slug":"server-returned-an-invalid-iteration-count-itera","errorCode":null,"errorMessage":"Server returned an invalid iteration count ${iterations}","messagePattern":"Server returned an invalid iteration count (.+?)","errorType":"exception","errorClass":"MongoRuntimeError","httpStatus":null,"severity":"error","filePath":"src/cmap/auth/scram.ts","lineNumber":147,"sourceCode":"  const nonce = authContext.nonce;\n\n  const db = credentials.source;\n  const username = cleanUsername(credentials.username);\n  const password = credentials.password;\n\n  const processedPassword =\n    cryptoMethod === 'sha256' ? saslprep(password) : passwordDigest(username, password);\n\n  const payload: Binary = ByteUtils.isUint8Array(response.payload)\n    ? new Binary(response.payload)\n    : response.payload;\n\n  const dict = parsePayload(payload);\n\n  const iterations = parseInt(dict.i, 10);\n  if (iterations && iterations < 4096) {\n    // TODO(NODE-3483)\n    throw new MongoRuntimeError(`Server returned an invalid iteration count ${iterations}`);\n  }\n\n  const salt = dict.s;\n  const rnonce = dict.r;\n  if (rnonce.startsWith('nonce')) {\n    // TODO(NODE-3483)\n    throw new MongoRuntimeError(`Server returned an invalid nonce: ${rnonce}`);\n  }\n\n  // Set up start of proof\n  const withoutProof = `c=biws,r=${rnonce}`;\n  const saltedPassword = await HI(\n    processedPassword,\n    ByteUtils.fromBase64(salt),\n    iterations,\n    cryptoMethod\n  );\n","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cmap/auth/scram.ts#L129-L165","documentation":"Thrown by continueScramConversation (scram.ts:147) when the server's SASL response reports an iteration count less than 4096. RFC 5802 mandates a minimum of 4096 PBKDF2 iterations for SCRAM-SHA-256; a lower value is either a non-compliant server or a sign of a tampered/downgrade attempt. Raised as MongoRuntimeError.","triggerScenarios":"The server's saslStart response payload contains an 'i' field (iteration count) that parses to a number greater than 0 but below 4096. The check skips when iterations is falsy/0 (legacy), so only an explicit low positive value triggers it.","commonSituations":"A misconfigured or very old MongoDB-compatible server advertising <4096 iterations. A man-in-the-middle tampering with the SASL payload to weaken key derivation. A non-conformant proxy/gateway rewriting the response.","solutions":["Upgrade or reconfigure the MongoDB server to advertise at least 4096 iterations","Remove any intermediary proxy/gateway that may rewrite SASL payloads","If using SCRAM-SHA-256, confirm the server supports the modern defaults","Treat this as a potential security incident and verify the connection is not being downgraded"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await client.connect();\n} catch (err) {\n  if (err instanceof MongoRuntimeError && /invalid iteration count/.test(err.message)) {\n    // server is non-compliant or downgrade attack; do NOT retry against same endpoint\n    alertSecurityTeam(err);\n  }\n  throw err;\n}","preventionTips":["Keep MongoDB servers upgraded to versions that advertise >=4096 iterations","Enable TLS to prevent tampering with the SASL exchange","Remove intermediaries (proxies/gateways) that could rewrite SASL payloads"],"tags":["scram","security","server","sasl","authentication"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}