mongodb/node-mongodb-native · error · MongoInvalidArgumentError

AuthContext must contain a valid nonce property

Error message

AuthContext must contain a valid nonce property

What it means

Thrown by executeScram (scram.ts:106) when authContext.nonce is unset. The nonce is generated during prepare() (scram.ts:35-37); reaching this throw means auth() was invoked without prepare() having populated the nonce first. Raised as MongoInvalidArgumentError. This is an internal ordering invariant: normal handshakes always run prepare before auth.

Solutions

  1. If reached via the public API, file a driver bug with a reproduction
  2. When invoking the internal provider directly, call prepare() before auth() so the nonce is set
  3. Upgrade the driver in case the ordering bug is already fixed

Example fix

// before (internal misuse)
await provider.auth(authContext); // nonce never set

// after
await provider.prepare(handshakeDoc, authContext);
await provider.auth(authContext);
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await client.connect();
} catch (err) {
  if (err instanceof MongoInvalidArgumentError && /nonce/.test(err.message)) {
    // internal ordering bug: report to driver maintainers with a reproduction
    reportDriverBug(err);
  }
  throw err;
}

Prevention

When it happens

Trigger: A code path that invokes ScramSHA.auth() directly without first calling ScramSHA.prepare(), or a driver regression where the handshake skipped the prepare step. Not reachable through the standard MongoClient connect flow.

Common situations: Forking or unit-testing the SCRAM provider by calling auth() in isolation. A driver bug where speculative auth and the non-speculative path interact to skip prepare(). Re-authentication after connection pool reset losing the nonce.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/374f56697d72b8cd. Report an issue: GitHub.

Appendix: source

Thrown at src/cmap/auth/scram.ts:106

  // Since the username is not sasl-prep-d, we need to do this here.
  return {
    saslStart: 1,
    mechanism,
    payload: new Binary(
      ByteUtils.concat([ByteUtils.fromUTF8('n,,'), clientFirstMessageBare(username, nonce)])
    ),
    autoAuthorize: 1,
    options: { skipEmptyExchange: true }
  };
}

async function executeScram(cryptoMethod: CryptoMethod, authContext: AuthContext): Promise<void> {
  const { connection, credentials } = authContext;
  if (!credentials) {
    throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
  }
  if (!authContext.nonce) {
    throw new MongoInvalidArgumentError('AuthContext must contain a valid nonce property');
  }
  const nonce = authContext.nonce;
  const db = credentials.source;

  const saslStartCmd = makeFirstMessage(cryptoMethod, credentials, nonce);
  const response = await connection.command(ns(`${db}.$cmd`), saslStartCmd, undefined);
  await continueScramConversation(cryptoMethod, response, authContext);
}

async function continueScramConversation(
  cryptoMethod: CryptoMethod,
  response: Document,
  authContext: AuthContext
): Promise<void> {
  const connection = authContext.connection;
  const credentials = authContext.credentials;
  if (!credentials) {
    throw new MongoMissingCredentialsError('AuthContext must provide credentials.');

View on GitHub (pinned to dce7939f86)