- Error code
- 18
- Code name
AuthenticationFailed- Product
- MongoDB
- Versions
- MongoDB 7.0 and 8.0 (wording checked against the 8.0 source)
- Category
- Authentication & Authorisation
- Last reviewed
- 24 October 2026
On this page
What it means
Error 18 (AuthenticationFailed) means the login was rejected: the user name, password, authentication database or mechanism did not match a user on the server.
When a client logs in with SCRAM (MongoDB's default mechanism), it proves it knows the password for a user stored in one specific database, the authentication database. If anything does not match, MongoDB 8.0 replaces the detailed reason with one fixed reply, Authentication failed., for every SASL failure apart from protocol and mechanism errors, so the client is not told whether the user exists. The real reason (for example an unknown user, or a SCRAM key mismatch for a wrong password) is written only to the server log, in the "Failed to authenticate" entry with the user, database, mechanism and error.
The most common cause is not the password itself but where the client looks for the user. The connection string option authSource names the authentication database; it defaults to the database in the URI path if there is one, otherwise admin. A user created in admin and a URI ending in /shop without authSource=admin therefore fails. The second classic cause is a password containing characters such as @ : / ? # [ ] $ that were not percent-encoded in the URI.
Common causes
- Wrong authentication database: the URI path names an application database, the user was created in admin, and
authSourceis missing. - Special characters in the user name or password are not percent-encoded in the connection string, so the driver sends a different password.
- Wrong or old password, for example after a rotation that did not reach every application instance or secret store.
- The user does not exist on this deployment (a different cluster, environment or Atlas project) or was dropped.
- The client asks for a mechanism the user's credentials do not support (for example SCRAM-SHA-256 for a user created with SCRAM-SHA-1 only).
Diagnose it
Read-only These mongosh commands only read data, indexes, statistics and server state (find, aggregate without $out or $merge, getIndexes, stats, currentOp, rs.status). They do not change data, users or settings, so they are safe to run first.
Read the real reason in the server log
db.adminCommand({ getLog: "global" }).log
.filter(line => line.includes("Failed to authenticate"))
.slice(-5)
.forEach(line => print(line)) The latest failed logins with user, db, mechanism and error. The db field shows which authentication database the client used; the error tells an unknown user from a wrong password. Run it from an administrative session; on Atlas, download the logs from the cluster instead.
Find where the user is defined
db.getSiblingDB("admin").runCommand({
usersInfo: { forAllDBs: true },
filter: { user: "appUser" }
}) Each user called appUser with its db (the authentication database) and mechanisms. Use that db as authSource. No result means the user does not exist on this deployment. Viewing users needs the viewUser action.
Ask the server which mechanisms the user supports
db.runCommand({ hello: 1, saslSupportedMechs: "admin.appUser" }).saslSupportedMechs An array such as [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]. In MongoDB 8.0 the field is left out when no such user exists in that database (the server logs "Supported SASL mechanisms requested for unknown user"), which points at the wrong authSource or user name.
Check how the password is encoded in the URI
encodeURIComponent("#MyP@ssword?") // "%23MyP%40ssword%3F" The encoded form to put in the connection string. If the URI contains the raw password with @, :, /, ? or #, the driver splits the string in the wrong place.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Set authSource to the user's database
Client or network sideAdd authSource with the database shown by usersInfo, while keeping the application database in the path.
mongodb://appUser:S3cret%40pass@db1.example.net:27017/shop?authSource=admin
Percent-encode the credentials
Client or network sideEncode the user name and password before building the URI (encodeURIComponent in JavaScript, urllib.parse.quote_plus in Python), or pass them as separate client options instead of inside the URI.
const uri = `mongodb://${encodeURIComponent(user)}:${encodeURIComponent(pass)}@db1.example.net:27017/?authSource=admin`
Reset the password for the right user
Changes permissionsWhen the password is genuinely wrong or unknown, an administrator sets a new one in the user's authentication database and the new secret is rolled out to every client. On Atlas, edit the database user in the Atlas UI or API.
Caution: Every client still using the old password fails with error 18 after the change. Update the secret store and restart or reload the applications in the same change window.
db.getSiblingDB("admin").changeUserPassword("appUser", passwordPrompt())
Match the mechanism to the user's credentials
Client or network sideNormally leave authMechanism unset so the driver negotiates it. If it is forced, choose one listed in the user's mechanisms from usersInfo.
mongodb://appUser:...@db1.example.net:27017/?authSource=admin&authMechanism=SCRAM-SHA-256
Examples
The user is in admin but the URI points at shop
Not reproduced here: no MongoDB server is installed for this site. The reply text is the fixed authenticationFailedStatus in MongoDB 8.0's source (authorization_manager.cpp), which the SASL commands return for every failure apart from protocol and mechanism errors. The connection string rules (authSource defaults to the path database) are from MongoDB's connection string options documentation.
// user created with db.getSiblingDB("admin").createUser({ user: "appUser", ... })
mongosh "mongodb://appUser:S3cret%40pass@db1.example.net:27017/shop"
MongoServerError: Authentication failed.
An unencoded @ in the password
Not reproduced here: no MongoDB server is installed for this site. MongoDB's documentation requires the characters $ : / ? # [ ] @ to be percent-encoded in credentials. Depending on the client, an unencoded @ makes the URI fail to parse or sends the wrong password; the result shows the second case and is illustrative.
// password is S3cret@pass
mongosh "mongodb://appUser:S3cret@pass@db1.example.net:27017/?authSource=admin"
MongoServerError: Authentication failed.
How to prevent it
Always write authSource explicitly in connection strings, keep credentials out of the URI where the driver allows separate options, and generate URIs with an encoding function rather than string concatenation.
Rotate passwords with an overlap plan (update every consumer, then retire the old secret) and monitor the "Failed to authenticate" log entries: a burst usually means one instance still has an old secret.
Common questions
Why does MongoDB not say whether the user or the password is wrong?
On purpose: the server sends the same Authentication failed. reply for every login failure so a client cannot probe which users exist. The detailed reason is in the server log entry "Failed to authenticate".
What is authSource and what should I set it to?
It is the database where the user was created. It defaults to the database in the URI path, or admin if the path is empty. Look up the user with usersInfo and set authSource to its db, usually admin.
What does "bad auth : authentication failed" mean on Atlas?
It is the wording MongoDB Atlas uses for a rejected login, listed with the authentication errors in the Node.js driver troubleshooting guide: usually the database user name or password is wrong. Check the database user in Atlas (not the Atlas account login) and percent-encode its password in the URI.
Official documentation
- MongoDB error codes (18 AuthenticationFailed)
- Connection string options (authSource, percent-encoding)
- Node.js driver connection troubleshooting (authentication error)
- SCRAM authentication
Last technically reviewed 24 October 2026; examples and diagnostics run on MongoDB 8.0 documentation and source (error_codes.yml r8.0.0); not run locally. Codes and code names are checked against MongoDB's error_codes.yml (8.0); no MongoDB server was available, so the examples were not run locally.