{"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/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/cmap/auth/scram.ts#L129-L165","documentation":"Thrown by continueScramConversation() (scram.ts:147) as a MongoRuntimeError when the server's SCRAM response contains an iteration count 'i' that is positive but below 4096. RFC 5802 and MongoDB's security policy require a minimum of 4096 PBKDF2 iterations; a lower value is either a misconfigured or compromised server, so the driver refuses to proceed.","triggerScenarios":"Server returns a SCRAM payload whose 'i' field parses to a number between 1 and 4095; the server was explicitly configured with a weak iteration count; a man-in-the-middle downgrade attack; a buggy/mock server.","commonSituations":"Connecting to an old or custom MongoDB-compatible server (e.g. some early Cosmos DB / DocumentDB / FerretDB versions) that advertised low iteration counts; test fixtures with hand-crafted SCRAM responses.","solutions":["Upgrade the target server to a version that enforces >= 4096 iterations","If using a MongoDB-compatible proxy/mock, fix its SCRAM response to use >= 4096 iterations","Verify network path integrity - a downgrade here can indicate tampering","Switch to SCRAM-SHA-256 which the server typically configures with stronger parameters"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await client.connect();\n} catch (e) {\n  if (e instanceof MongoRuntimeError && /iteration count/i.test(e.message)) {\n    // server is misconfigured or non-genuine; upgrade or switch target\n  }\n  throw e;\n}","preventionTips":["Run genuine MongoDB 4.0+ which enforces >= 10000 iterations by default","Avoid MongoDB-compatible emulators that misconfigure SCRAM parameters","Prefer SCRAM-SHA-256 for stronger defaults"],"tags":["auth","scram","security","server-config","pbkdf2"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}