{"record":{"id":"d4d501ba6f272b32","repo":"mongodb/node-mongodb-native","slug":"server-returned-an-invalid-nonce-rnonce","errorCode":null,"errorMessage":"Server returned an invalid nonce: ${rnonce}","messagePattern":"Server returned an invalid nonce: (.+?)","errorType":"exception","errorClass":"MongoRuntimeError","httpStatus":null,"severity":"error","filePath":"src/cmap/auth/scram.ts","lineNumber":154,"sourceCode":"    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\n  const clientKey = await HMAC(cryptoMethod, saltedPassword, 'Client Key');\n  const serverKey = await HMAC(cryptoMethod, saltedPassword, 'Server Key');\n  const storedKey = await H(cryptoMethod, clientKey);\n  const firstMessageBytes = clientFirstMessageBare(username, nonce);\n  const firstMessage = ByteUtils.toUTF8(firstMessageBytes, 0, firstMessageBytes.length, false);\n  const payloadString = ByteUtils.toUTF8(payload.buffer, 0, payload.position, false);\n  const authMessage = [firstMessage, payloadString, withoutProof].join(',');","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cmap/auth/scram.ts#L136-L172","documentation":"Thrown by continueScramConversation (scram.ts:154) when the server's combined nonce (rnonce) does not pass the driver's sanity check. The driver rejects a server nonce that starts with the literal 'nonce', which indicates a malformed or non-conformant server response. The server's rnonce must begin with the client's nonce. Raised as MongoRuntimeError.","triggerScenarios":"The server's SASL payload 'r' field (rnonce) starts with the substring 'nonce'. This is the guard in code (rnonce.startsWith('nonce')); a legitimate server never produces such a value, so its presence signals a corrupt or malicious response.","commonSituations":"A buggy/non-conformant MongoDB-compatible server returning an unexpected nonce format. A proxy or MITM injecting a placeholder 'nonce' value. A corrupted SASL payload from a misbehaving load balancer.","solutions":["Verify you are connecting to a genuine MongoDB server of a supported version","Remove any intermediary (proxy, LB, gateway) that may corrupt the SASL exchange","Check for MITM/TLS termination that rewrites the authentication payload","Report to the server vendor if using a MongoDB-compatible database"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await client.connect();\n} catch (err) {\n  if (err instanceof MongoRuntimeError && /invalid nonce/.test(err.message)) {\n    // likely a non-conformant/spoofed server or a corrupting proxy; investigate\n    alertSecurityTeam(err);\n  }\n  throw err;\n}","preventionTips":["Connect only to genuine, supported MongoDB servers","Enable TLS and verify certificates to prevent SASL tampering","Avoid proxies/load balancers that may corrupt authentication 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"}