mongodb/node-mongodb-native · critical · MongoRuntimeError

Node.js crypto module is required for SCRAM-SHA-1…

Error message

Node.js crypto module is required for SCRAM-SHA-1 authentication

What it means

Thrown as a MongoRuntimeError (with the caught require error as cause) when require('crypto') fails inside passwordDigest(). The Node.js 'crypto' built-in module is required specifically for the SCRAM-SHA-1 MD5 digest; the SCRAM-SHA-256 path uses the WebCrypto global (crypto.subtle) instead. A failing require of a built-in module is abnormal and signals a broken or non-standard runtime.

Solutions

  1. Run the driver in a standard Node.js runtime where the 'crypto' built-in is available
  2. If targeting a bundler, mark 'crypto' as external (webpack node.exports or esbuild --external:crypto)
  3. Switch the auth mechanism to SCRAM-SHA-256 (which uses WebCrypto) if the environment supports crypto.subtle but not the crypto module
  4. Reinstall or repair the Node.js installation if the built-in module is genuinely missing

Example fix

// before: SCRAM-SHA-1 requires Node crypto module
const client = new MongoClient('mongodb://user:pass@host/db?authMechanism=SCRAM-SHA-1');

// after: prefer SCRAM-SHA-256 (server 4.0+) which uses WebCrypto
const client = new MongoClient('mongodb://user:pass@host/db?authMechanism=SCRAM-SHA-256');
Defensive patterns

Strategy: validation

Validate before calling

let cryptoOk = true;
try { require('crypto'); } catch { cryptoOk = false; }
if (!cryptoOk && uri.includes('SCRAM-SHA-1')) {
  throw new Error('SCRAM-SHA-1 needs Node crypto module; use SCRAM-SHA-256 or run under Node');
}

Type guard

function nodeCryptoAvailable(): boolean {
  try { require('crypto'); return true; } catch { return false; }
}

Prevention

When it happens

Trigger: Authenticating via SCRAM-SHA-1 in an environment where the Node.js 'crypto' built-in is unavailable or blocked: certain bundlers (webpack/browserify) that shim require(), sandboxed serverless runtimes that strip built-ins, or a corrupted Node.js install. Also reachable if a custom module loader intercepts require('crypto').

Common situations: Bundling the driver for a browser/edge runtime that lacks Node 'crypto'; running under a hardened Lambda/container that blocks the crypto native addon; a misconfigured ts-serverless or esbuild setup that polyfills 'crypto' with an error stub.

Understand the failure class

Related errors


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

Appendix: source

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

  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');
    md5.update(`${username}:mongo:${password}`, 'utf8');
    return md5.digest('hex');
  } catch (err) {
    if (nodeCrypto.getFips()) {
      // This error is (slightly) more helpful than what comes from OpenSSL directly, e.g.
      // 'Error: error:060800C8:digital envelope routines:EVP_DigestInit_ex:disabled for FIPS'
      throw new Error('Auth mechanism SCRAM-SHA-1 is not supported in FIPS mode');
    }
    throw err;

View on GitHub (pinned to dce7939f86)