mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Password cannot be empty

Error message

Password cannot be empty

What it means

Thrown as a MongoInvalidArgumentError inside passwordDigest() when the SCRAM-SHA-1 code path receives an empty password string. passwordDigest() is only invoked for the SCRAM-SHA-1 mechanism (sha256 uses saslprep instead), so this specifically guards the legacy MD5-based digest step. The check exists because an empty password produces an invalid MD5 digest and would yield a confusing server-side auth failure later.

Solutions

  1. Supply a non-empty password in the connection string (mongodb://user:pass@host/db) or in the credentials passed to MongoClient
  2. If auth is not required, remove the username from the URI so the driver does not attempt SCRAM
  3. Verify the password environment variable is populated before constructing the MongoClient (check for empty string, not just undefined)

Example fix

// before
const client = new MongoClient('mongodb://myuser@host:27017/db');

// after
const client = new MongoClient('mongodb://myuser:s3cret@host:27017/db');
Defensive patterns

Strategy: validation

Validate before calling

const uri = process.env.MONGODB_URI ?? '';
if (/^[^:]*:[^:@]*@/.test(uri) && /:\/\/[^:@]*:@/.test(uri)) {
  throw new Error('MongoDB URI contains an empty password');
}
// or, with explicit credentials:
const { username, password } = creds;
if (username && !password) throw new Error('Username set but password is empty');

Type guard

function hasValidPassword(creds: { username?: string; password?: string }): boolean {
  return typeof creds.password === 'string' && creds.password.length > 0;
}

Try / catch

try {
  await client.connect();
} catch (e) {
  if (e instanceof MongoInvalidArgumentError && /Password cannot be empty/.test(e.message)) {
    // fix credentials and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Connecting or authenticating with authMechanism 'SCRAM-SHA-1' (or MONGODB_DEFAULT that the server negotiates down to SCRAM-SHA-1) where the credentials object has a username but password === ''. Occurs during the SCRAM conversation in continueScramConversation() -> passwordDigest(username, password).

Common situations: Setting MONGODB_URI with username but no password (e.g. mongodb://user@host/db), reading credentials from an env var that is unset/empty, a service account whose password was rotated to empty, or a typo dropping the password segment of the URI.

Related errors


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

Appendix: source

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

  const parts = payloadStr.split(',');
  for (let i = 0; i < parts.length; i++) {
    const valueParts = (parts[i].match(/^([^=]*)=(.*)$/) ?? []).slice(1);
    dict[valueParts[0]] = valueParts[1];
  }
  return dict;
}

function passwordDigest(username: string, password: string) {
  if (typeof username !== 'string') {
    throw new MongoInvalidArgumentError('Username must be a string');
  }

  if (typeof password !== 'string') {
    throw new MongoInvalidArgumentError('Password must be a string');
  }

  if (password.length === 0) {
    throw new MongoInvalidArgumentError('Password cannot be empty');
  }

  let nodeCrypto;
  try {
    // TODO: NODE-7424 - remove dependency on 'crypto' for SCRAM-SHA-1 authentication
    // eslint-disable-next-line @typescript-eslint/no-require-imports
    nodeCrypto = require('crypto');
  } catch (e) {
    throw new MongoRuntimeError(
      'Node.js crypto module is required for SCRAM-SHA-1 authentication',
      {
        cause: e
      }
    );
  }

  try {
    const md5 = nodeCrypto.createHash('md5');

View on GitHub (pinned to dce7939f86)