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

  1. Provide credentials with the X.509 subject as username: new MongoClient(url, { auth: { username: 'CN=...,OU=...' }, authMechanism: 'MONGODB-X509' })
  2. Ensure the TLS certificate (cert/key) is configured via tlsCertFile/tlsKeyFile so the server can identify the client
  3. 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

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


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)