mongodb/node-mongodb-native · error · MongoRuntimeError
Server returned an invalid nonce: ${rnonce}
Error message
Server returned an invalid nonce: ${rnonce} What it means
Thrown by continueScramConversation() (scram.ts:154) as a MongoRuntimeError when the combined nonce returned by the server (rnonce) starts with the literal string 'nonce'. In a valid SCRAM exchange the server must return the client's nonce with its own suffix prepended; a response literally beginning with 'nonce' indicates a malformed or test/placeholder server response.
Source
Thrown at src/cmap/auth/scram.ts:154
cryptoMethod === 'sha256' ? saslprep(password) : passwordDigest(username, password);
const payload: Binary = ByteUtils.isUint8Array(response.payload)
? new Binary(response.payload)
: response.payload;
const dict = parsePayload(payload);
const iterations = parseInt(dict.i, 10);
if (iterations && iterations < 4096) {
// TODO(NODE-3483)
throw new MongoRuntimeError(`Server returned an invalid iteration count ${iterations}`);
}
const salt = dict.s;
const rnonce = dict.r;
if (rnonce.startsWith('nonce')) {
// TODO(NODE-3483)
throw new MongoRuntimeError(`Server returned an invalid nonce: ${rnonce}`);
}
// Set up start of proof
const withoutProof = `c=biws,r=${rnonce}`;
const saltedPassword = await HI(
processedPassword,
ByteUtils.fromBase64(salt),
iterations,
cryptoMethod
);
const clientKey = await HMAC(cryptoMethod, saltedPassword, 'Client Key');
const serverKey = await HMAC(cryptoMethod, saltedPassword, 'Server Key');
const storedKey = await H(cryptoMethod, clientKey);
const firstMessageBytes = clientFirstMessageBare(username, nonce);
const firstMessage = ByteUtils.toUTF8(firstMessageBytes, 0, firstMessageBytes.length, false);
const payloadString = ByteUtils.toUTF8(payload.buffer, 0, payload.position, false);
const authMessage = [firstMessage, payloadString, withoutProof].join(',');View on GitHub (pinned to 3366c21a63)
Solutions
- Connect to a genuine MongoDB deployment (community, enterprise, or Atlas)
- If testing against a mock, ensure it echoes the client nonce correctly per RFC 5802
- Inspect network path for a misbehaving proxy or MITM
Defensive patterns
Strategy: try-catch
Try / catch
try {
await client.connect();
} catch (e) {
if (e instanceof MongoRuntimeError && /invalid nonce/i.test(e.message)) {
// server returned a malformed SCRAM response; verify it is genuine MongoDB
}
throw e;
} Prevention
- Use genuine MongoDB deployments
- Ensure any proxy/load-balancer passes SCRAM payloads through unchanged
- For test doubles, implement RFC 5802 nonce echoing correctly
When it happens
Trigger: Server's saslStart response payload has an 'r=' field whose value literally starts with the characters 'nonce' rather than echoing the client nonce. Seen with broken SCRAM implementations in MongoDB-compatible emulators or hand-crafted test harnesses.
Common situations: Connecting to a non-genuine MongoDB service that emits a default/placeholder SCRAM nonce; a malformed interception by a proxy; an internal test double returning canned responses.
Related errors
- Server returned an invalid iteration count ${iterations}
- Server returned an invalid signature
- Password cannot be empty
- Username required for mechanism '${this.mechanism}'
- Server nonce does not begin with client nonce
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/d4d501ba6f272b32.json.
Report an issue: GitHub.