MongoDB authSource Gotcha: Why Your User Works on the CLI but Fails in Code
Adam C. |

If you've ever run into a confusing MongoDB auth error — where your user works in mongosh but not in your app — the culprit may be a subtle but critical detail: the authSource.

Photo by JOHN TOWNER on Unsplash

The Problem

You create a user like this:

db.createUser({
  user: "nodebb",
  pwd: "dfd!",
  roles: [
    { role: "readWrite", db: "nodebb" },
    { role: "clusterMonitor", db: "admin" }
  ]
})

Then try to connect from PHP, Node.js, or another client:

mongodb://nodebb:dfd!@localhost:27017/nodebb?authSource=admin

✅ It works in mongosh if you do this:

mongosh -u nodebb -p --authenticationDatabase nodebb

❌ But your app fails to connect.

Why?

The Reason: authSource=admin is Wrong (in this Case)

When you use authSource=admin, MongoDB looks for the user in the admin database. But in this example, the user was created in the nodebb database.

Unless you explicitly created the user in admin, you must match the authSource to the database where the user was created.

The Fix

If you created the user in the nodebb database, then use:

mongodb://nodebb:dfd%21@localhost:27017/?authSource=nodebb

✅ Note: ! must be URL encoded as %21

Now everything works:

MongoDB\Client->selectDatabase('nodebb') in PHP

mongoose.connect(...) in Node.js

Any other MongoDB client

Do I need to include /nodebb in the URI path?

No — you only need to include authSource=nodebb.
The /nodebb path in the URI (i.e. ...@localhost:27017/nodebb) simply sets the default database used if you don’t call selectDatabase() in your code.

If you do call selectDatabase('nodebb') manually — which you should — the path segment is optional.

TL;DR

authSource must match the database where the user was created

If you omit it, some drivers may default to admin, which fails silently

Always URL-encode special characters in passwords in your Mongo URI

The /database path in the URI is optional if you manually call selectDatabase() in code

This tiny mistake can cause hours of frustration — now you know how to avoid it.