{"id":"374f56697d72b8cd","repo":"mongodb/node-mongodb-native","slug":"authcontext-must-contain-a-valid-nonce-property","errorCode":null,"errorMessage":"AuthContext must contain a valid nonce property","messagePattern":"AuthContext must contain a valid nonce property","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/cmap/auth/scram.ts","lineNumber":106,"sourceCode":"  // Since the username is not sasl-prep-d, we need to do this here.\n  return {\n    saslStart: 1,\n    mechanism,\n    payload: new Binary(\n      ByteUtils.concat([ByteUtils.fromUTF8('n,,'), clientFirstMessageBare(username, nonce)])\n    ),\n    autoAuthorize: 1,\n    options: { skipEmptyExchange: true }\n  };\n}\n\nasync function executeScram(cryptoMethod: CryptoMethod, authContext: AuthContext): Promise<void> {\n  const { connection, credentials } = authContext;\n  if (!credentials) {\n    throw new MongoMissingCredentialsError('AuthContext must provide credentials.');\n  }\n  if (!authContext.nonce) {\n    throw new MongoInvalidArgumentError('AuthContext must contain a valid nonce property');\n  }\n  const nonce = authContext.nonce;\n  const db = credentials.source;\n\n  const saslStartCmd = makeFirstMessage(cryptoMethod, credentials, nonce);\n  const response = await connection.command(ns(`${db}.$cmd`), saslStartCmd, undefined);\n  await continueScramConversation(cryptoMethod, response, authContext);\n}\n\nasync function continueScramConversation(\n  cryptoMethod: CryptoMethod,\n  response: Document,\n  authContext: AuthContext\n): Promise<void> {\n  const connection = authContext.connection;\n  const credentials = authContext.credentials;\n  if (!credentials) {\n    throw new MongoMissingCredentialsError('AuthContext must provide credentials.');","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/cmap/auth/scram.ts#L88-L124","documentation":"Thrown by executeScram() (scram.ts:106) as a MongoInvalidArgumentError when authContext.nonce is falsy at the point of building the SCRAM first message. The nonce is normally generated in prepare(); reaching executeScram without one means the handshake was short-circuited or the AuthContext was constructed incorrectly. This is an internal-state violation rather than a user input error.","triggerScenarios":"Calling executeScram directly (bypassing prepare()); an AuthContext built manually without invoking prepare() first; a defect where prepare() failed to set the nonce after an earlier thrown error was swallowed.","commonSituations":"Driver bug or monkey-patching the auth provider; using an internal API in a non-standard order; an earlier exception during randomBytes(24) being caught and ignored before nonce assignment.","solutions":["Avoid bypassing the standard connect/handshake flow - let the driver call prepare() then auth()","If you subclass ScramSHA, ensure super.prepare() runs and sets authContext.nonce","Report as a driver bug if reached with an unmodified MongoClient - include driver version and repro"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await client.connect();\n} catch (e) {\n  if (e instanceof MongoInvalidArgumentError && /nonce/.test(e.message)) {\n    // internal state issue - report to driver maintainers with full repro\n  }\n  throw e;\n}","preventionTips":["Do not bypass prepare() when subclassing ScramSHA","Report this as a bug if reached with an unmodified driver","Pin a known-good driver version if a regression is suspected"],"tags":["auth","scram","nonce","internal-state"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}