This post is out of date and here for archive purposes only.

 

June 4, 2014

Creating user accounts is a simple process. But if you’re not paying attention, there are a number of places you might be confounded along the way with MongoDB, including deprecated commands, new parameters, syntactical nuances, bugs, and incompatibilities.

 

Bugs

Shell Methods vs. Database Commands

If you come across “Error: 18 { ok: 0.0, errmsg: “auth failed”, code: 18 } at src/mongo/shell/db.js:1210” and you’re authenticating with the correct password, the account might have been created with a syntactical error.

Can you spot the difference between db.runCommand() and db.createUser() below?

When they’re shown next to each other like this, you probably can. Lines 6 and 17 are different. The db.createUser() method uses a field named “user,” while db.runCommand() uses a field named “createUser.” Syntactically, this makes sense. A “createUser” field in a db.createUser() method would feel redundant. But you’ll be in for some confusion if you mistakenly use “createUser” instead of “user” with the db.createUser() method.

What happens if you mix the syntax? If you use the “createUser” field (instead of “user”) with the db.createUser() shell command, the account is created and the mongo client displays a success message. But it turns out that you can’t authenticate to the account. Here’s an example of creating a user with the incorrect field name.

In the first example, we created “someuser1” and “someuser2” with correct syntax. In the next example, we created “someuser3′ with a syntactical error. Let’s verify that all three accounts exist:

The account “someuser3” does exist, but if we try to authenticate with it, we get an error:
2014-06-01T16:32:14.882+0000 Error: 18 { ok: 0.0, errmsg: “auth failed”, code: 18 } at src/mongo/shell/db.js:1210

 

There is an easy fix for this besides just using the correct syntax. Changing the password on the account is sufficient to resolve the error.

We can now authenticate with the account successfully.

 

The mongo shell provides quick access to MongoDB without having to use a language client library. These shell methods wrap database commands using JavaScript and attempt a more intuitive syntax than running database commands directly. However, database commands can also be run directly using the db.runCommand() helper right from the mongo shell. In fact, the MongoDB documentation goes so far as to say, “This is the preferred method for issuing database commands, as it provides a consistent interface between the shell and drivers.

When referencing the MongoDB documentation, syntax can be a little confusing in that the shell commands and database commands (docs.mongodb.org) are documented in the same “space” as opposed to the driver and client library API documentation (api.mongodb.org).

 

{ getLog: “startupWarnings” } Bug

In the example above, you probably noticed another error:
Error while trying to show server startup warnings: not authorized on admin to execute command { getLog: “startupWarnings” }

This is a bug in version 2.6.0 and 2.6.1 that has been fixed in 2.6.2 and 2.7.0. Testing the account shows that it has the expected permissions.

Everything works as expected; this isn’t a valid error.

 

Command, Parameter, and Schema Changes

–authenticationDatabase

This parameter was added in version 2.4. Without the authenticationDatabase parameter, mongo attempts to authenticate to the database to which you’re connecting. In the following example, the authenticationDatabase parameter isn’t specified, and therefore mongo attempts to authenticate “someuser3” to “somedatabase”.

If however, that account exists in “anotherdatabase,” and assuming the account also has access to “somedatabase” the correct syntax would be:

Nothing too complex here, unless you’re upgrading from a version prior to 2.4 and get caught off guard with this one.

 

addUser() vs. createUser()

Another change is the deprecation of db.addUser() in favor of db.createUser() in version 2.6. This resulted in an incompatibility with Robomongo 0.8.4, for example, which uses the MongoDB shell version 2.4. If at the time of this writing you use the current version of MonboDB (2.6.1) with the current Robomongo (0.8.4), you’ll run into a couple of problems. Robomongo is still a great tool and I’m sure it will get updated soon, but for now it’s an example of another place in which you can get tripped up.

 

Schema Changes

The schema of db.system.users changed in MongoDB versions 2.4 and 2.6. As of version 2.6, account information is stored in the “admin” database, even for users that are created in non-admin databases (which will be the case for most accounts). If you create a user in “Accounting,” the account will be stored in “admin,” which might throw you when you go looking for account information. The  authenticating database is still “Accounting” despite the account information being stored in “admin” and it is still correct for a user to pass
--authenticationDatabase 'Accounting' to the mongo client when logging in.

The following diagram illustrates this.

MongoDB Authentication

 

Closing Thoughts

Version 2.6 brought a lot of great changes to MongoDB. But as the platform continues to evolve, there are plenty of places to get tripped up during an upgrade or while researching a problem. This post highlights topics specific to account creation, but the takeaways are the same for other topics as well; Pay close attention to version changes (especially when planning during upgrades). Be careful to differentiate between core database commands and the shell methods and client libraries that wrap them. And if you’re hitting your head against a problem for a long time, check MongoDB’s Jira site for reported issues; it may well just be a bug.