mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Password must be a string
Error message
Password must be a string
What it means
Thrown by passwordDigest (scram.ts:223) when the password passed to it is not a string. The SCRAM-SHA-1 MD5 digest requires a string password; a non-string password (undefined, number, object) cannot be hashed. Raised as MongoInvalidArgumentError. This is an internal type guard; credential parsing normally guarantees a string password before reaching SCRAM.
Solutions
- Ensure password is a non-empty string when constructing credentials
- If using the internal API, coerce password to string before it reaches SCRAM
- Prefer SCRAM-SHA-256 which routes through saslprep instead of passwordDigest
- Report a driver bug if reached via the public API
Example fix
// before
const credentials = { username: 'u', password: undefined, mechanism: 'SCRAM-SHA-1' };
// after
const credentials = { username: 'u', password: 'correct-horse', mechanism: 'SCRAM-SHA-1' }; Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof clientOptions.auth?.password !== 'string') {
throw new TypeError('auth.password must be a string');
} Type guard
function isStringPassword(auth: { password?: unknown }): auth is { password: string } {
return typeof auth.password === 'string' && auth.password.length > 0;
} Try / catch
try {
await client.connect();
} catch (err) {
if (err instanceof MongoInvalidArgumentError && /Password must be a string/.test(err.message)) {
// supply a valid string password and retry
} else throw err;
} Prevention
- Always pass string credentials via the public MongoClient options
- Validate auth.password is a non-empty string at config-load time
- Prefer SCRAM-SHA-256, which routes through saslprep rather than passwordDigest
When it happens
Trigger: passwordDigest invoked on the SCRAM-SHA-1 path with a password that is not a string. Reachable only if credentials.password is undefined/null/non-string when SCRAM-SHA-1 runs, bypassing normal credential parsing.
Common situations: A driver regression or fork where credentials.password is not coerced to a string. Programmatic MongoCredentials construction with a non-string password. Note: an empty string password throws a separate 'Password cannot be empty' error just below.
Related errors
- Username must be a string
- AuthContext must contain a valid nonce property
- No AuthProvider for defined.
- Unable to continue SCRAM without valid nonce
- Auth mechanism SCRAM-SHA-1 is not supported in FIPS mode
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/b2914ba2d36e8d57.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmap/auth/scram.ts:223
function parsePayload(payload: Binary) {
const payloadStr = ByteUtils.toUTF8(payload.buffer, 0, payload.position, false);
const dict: Document = {};
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
}
);View on GitHub (pinned to dce7939f86)