{"id":"f46d8eb1cc864033","repo":"mongodb/node-mongodb-native","slug":"authcontext-must-provide-credentials-f46d8e","errorCode":null,"errorMessage":"AuthContext must provide credentials.","messagePattern":"AuthContext must provide credentials\\.","errorType":"exception","errorClass":"MongoMissingCredentialsError","httpStatus":null,"severity":"error","filePath":"src/cmap/auth/plain.ts","lineNumber":10,"sourceCode":"import { Binary, ByteUtils } from '../../bson';\nimport { MongoMissingCredentialsError } from '../../error';\nimport { ns } from '../../utils';\nimport { type AuthContext, AuthProvider } from './auth_provider';\n\nexport class Plain extends AuthProvider {\n  override async auth(authContext: AuthContext): Promise<void> {\n    const { connection, credentials } = authContext;\n    if (!credentials) {\n      throw new MongoMissingCredentialsError('AuthContext must provide credentials.');\n    }\n\n    const { username, password } = credentials;\n\n    const payload = new Binary(ByteUtils.fromUTF8(`\\x00${username}\\x00${password}`));\n    const command = {\n      saslStart: 1,\n      mechanism: 'PLAIN',\n      payload: payload,\n      autoAuthorize: 1\n    };\n\n    await connection.command(ns('$external.$cmd'), command, undefined);\n  }\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/cmap/auth/plain.ts#L1-L26","documentation":"Thrown by the PLAIN (LDAP) auth provider when the AuthContext has no credentials at the start of authentication (src/cmap/auth/plain.ts:9). MONGODB-PLAIN forwards a username and password to the server's LDAP backend via the SASL PLAIN mechanism. Surfaced as a MongoMissingCredentialsError.","triggerScenarios":"Connecting with authMechanism=PLAIN but omitting username and/or password, or when the credential merge step yields no credentials object. The PLAIN provider immediately checks for credentials and throws before sending the saslStart command.","commonSituations":"Forgot to include username/password in the URI when using LDAP auth, set them as empty strings, or pointed at $external auth source with no creds. Also common when the connection string parser did not pick up the credentials due to URL-encoding issues.","solutions":["Provide username and password in the connection string with authMechanism=PLAIN and authSource=$external.","Ensure the credentials are URL-encoded if they contain special characters.","Confirm the LDAP backend on the MongoDB server is configured and the user exists in the directory.","Verify the driver is using authSource=$external (PLAIN/LDAP always uses $external)."],"exampleFix":"// before\nconst c = new MongoClient('mongodb://host/?authMechanism=PLAIN');\n\n// after\nconst c = new MongoClient(\n  'mongodb://ldapuser:ldappass@host/?authMechanism=PLAIN&authSource=%24external'\n);","handlingStrategy":"validation","validationCode":"function validatePlainCredentials(uri: string): void {\n  if (!/authMechanism=PLAIN/i.test(uri)) return;\n  if (!/(\\/\\/)[^:\\/]+:[^@]+@/.test(uri)) {\n    throw new Error('PLAIN (LDAP) auth requires username:password in the connection string');\n  }\n  if (!/authSource=%24external|authSource=\\$external/i.test(uri)) {\n    console.warn('PLAIN auth should use authSource=$external');\n  }\n}\nvalidatePlainCredentials(connectionString);","typeGuard":null,"tryCatchPattern":"try {\n  await client.connect();\n} catch (e) {\n  if (e instanceof MongoMissingCredentialsError && /AuthContext must provide credentials/.test(e.message) && mechanism === 'PLAIN') {\n    throw new Error('LDAP/PLAIN auth requires username and password (authSource=$external).');\n  }\n  throw e;\n}","preventionTips":["Always include username:password in the URI when using authMechanism=PLAIN.","URL-encode credentials containing special characters.","Set authSource=$external for LDAP/PLAIN auth.","Verify the LDAP user exists in the directory before app start."],"tags":["auth","plain","ldap","credentials","configuration"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}