mongodb/node-mongodb-native · error · MongoMissingCredentialsError
AuthContext must provide credentials.
Error message
AuthContext must provide credentials.
What it means
Thrown as a MongoMissingCredentialsError in X509.prepare() when authContext.credentials is falsy. prepare() builds the speculativeAuthenticate portion of the handshake for MONGODB-X509; without credentials there is no subject to authenticate. This fires during the initial handshake document construction (prepareHandshakeDocument).
Solutions
- Provide credentials with the X.509 subject as username: new MongoClient(url, { auth: { username: 'CN=...,OU=...' }, authMechanism: 'MONGODB-X509' })
- Ensure the TLS certificate (cert/key) is configured via tlsCertFile/tlsKeyFile so the server can identify the client
- Verify the credentials object is not being stripped or overwritten before connect()
Example fix
// before
const client = new MongoClient('mongodb://host/db?authMechanism=MONGODB-X509&tls=true');
// after
const client = new MongoClient('mongodb://host/db?tls=true', {
authMechanism: 'MONGODB-X509',
tlsCertFile: './client.pem',
auth: { username: 'CN=client,OU=eng,O=myorg' }
}); Defensive patterns
Strategy: validation
Validate before calling
if (options.authMechanism === 'MONGODB-X509' && !(options.auth?.username)) {
throw new Error('MONGODB-X509 requires the certificate subject as username');
} Type guard
function hasX509Credentials(opts: { authMechanism?: string; auth?: { username?: string } }): boolean {
return opts.authMechanism === 'MONGODB-X509' && typeof opts.auth?.username === 'string' && opts.auth.username.length > 0;
} Try / catch
try { await client.connect(); } catch (e) {
if (e instanceof MongoMissingCredentialsError) { /* supply X509 username */ }
throw e;
} Prevention
- Always pass the X.509 certificate subject as the username for MONGODB-X509
- Configure tlsCertFile/tlsKeyFile alongside the X509 mechanism
- Centralize X509 subject extraction from the certificate so the username is always set
When it happens
Trigger: Configuring the driver with authMechanism=MONGODB-X509 (or having it resolved to MONGODB-X509) but providing no credentials object, or a credentials object that resolves to null. The provider's prepare() is invoked from prepareHandshakeDocument() during connect().
Common situations: Setting ?authMechanism=MONGODB-X509 in the URI without a username; using x509 for inter-cluster auth but forgetting to pass the client certificate subject as the username; misconfigured service mesh that strips credentials.
Related errors
- Password not allowed for mechanism MONGODB-X509
- AuthContext must provide credentials.
- AuthContext must provide credentials.
- AuthContext must provide credentials.
- AuthContext must provide credentials.
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/f04d4e2ac5e76872.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmap/auth/x509.ts:15
import type { Document } from '../../bson';
import { MongoMissingCredentialsError } from '../../error';
import { ns } from '../../utils';
import type { HandshakeDocument } from '../connect';
import { type AuthContext, AuthProvider } from './auth_provider';
import type { MongoCredentials } from './mongo_credentials';
export class X509 extends AuthProvider {
override async prepare(
handshakeDoc: HandshakeDocument,
authContext: AuthContext
): Promise<HandshakeDocument> {
const { credentials } = authContext;
if (!credentials) {
throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
}
return { ...handshakeDoc, speculativeAuthenticate: x509AuthenticateCommand(credentials) };
}
override async auth(authContext: AuthContext) {
const connection = authContext.connection;
const credentials = authContext.credentials;
if (!credentials) {
throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
}
const response = authContext.response;
if (response?.speculativeAuthenticate) {
return;
}
await connection.command(ns('$external.$cmd'), x509AuthenticateCommand(credentials), undefined);
}View on GitHub (pinned to dce7939f86)