What is correct MongoClient Connection String for ReplicaSet with Auth?

20,067 views
Skip to first unread message

Jaan Paljasma

unread,
Dec 10, 2012, 10:39:32 AM12/10/12
to node-mong...@googlegroups.com
I have a problem with MongoClient throwing error. Have ReplicaSet here, and auth has been enabled for db level.

My connection string looks like this:
mongodb://user:pass@server1:27017,server2:27017/dbname?w=majority&replicaSet=rs&readPreference=secondary

When I try to read data, I get exception
AssertionError: null == "unauthorized db:dbname ns:dbname.collection lock type:0 client:<ip.address>"

With readPreference=primary or readPreference=primaryPreferred it works just fine, so problem must be with authenticating against secondary.
When I try to pass user and pass for second server, I simply get AssertionError: null == {"name":"MongoError","errmsg":"auth fails","ok":0}

I sure can read data from both servers when I log in with mongo client from the app machine.

1. What is the correct Connection string for RS with Auth?
2. Can MongoClient automatically find all RS members and do read from secondaries?

Thank you in advance,

Jaan Paljasma

unread,
Dec 10, 2012, 1:16:08 PM12/10/12
to node-mong...@googlegroups.com
Also, what is interesting, is that when you connect with the same connection string, but primary actually IS down, there are no errors and I can read data from my collection.
I am assuming there is something wrong with either my connection string syntax or MongoClient.connect() internal which does not authenticate against secondary if primary is available.

Until then, I have to use readPreference=primaryPreferred and hope for the best.

If anyone can shed a light, I would appreciate,

christkv

unread,
Dec 11, 2012, 8:15:53 AM12/11/12
to node-mong...@googlegroups.com
there is definitively something weird going on, I can reproduce it so checking

christkv

unread,
Dec 11, 2012, 10:55:48 AM12/11/12
to node-mong...@googlegroups.com
Fixed and pushed to npm as 1.2.4m update your npm package.

Jaan Paljasma

unread,
Dec 11, 2012, 1:39:38 PM12/11/12
to node-mong...@googlegroups.com
Hello, this somewhat seemed to fix this particular exception, however I still do get lots of errors when trying to open for example 100 MongoClients in a loop and ask them to do a query.
Could it be a connection pool issue?

If I do a loop like this (10 calls) everything is fine. Even loop with 20 is fine.
Increasing loop to 30 causes "TypeError: Cannot set property '_used' of null" and immediately (because collection is null) TypeError: Cannot call method 'collection' of null

for(i=0;i<10;i++) {
   MongoClient.connect(config.db.url, { native_parser:true, auto_reconnect: true }, function(err, db) {
   db.collection('hotels').findOne({_id:'alden'}, function(err, row){
       assert.equal(null, err);
console.log(row);
db.close(function(){});
   });
});
}


Interestingly, why 20 is OK, and 30 is not OK? Connection timeout? (servers are over WAN)
If you could tackle this issue as well then MongoClient will be way more solid - right now it fails too many times even though it should auto-reconnect and everything.

Thank you,

christkv

unread,
Dec 11, 2012, 1:53:25 PM12/11/12
to node-mong...@googlegroups.com
yeah you don't do this :) You open do MongoClient.connect once when your app boots up and reuse the db object. It's not a singleton connection pool each .connect creates a new connection pool. So open it once an reuse across all requests.

Jaan Paljasma

unread,
Dec 11, 2012, 2:01:33 PM12/11/12
to node-mong...@googlegroups.com
Thanks for the clarification.

I did some load tests today with my simple HTTP application, doing a load test. Under 15+ concurrent users, I started seeing this issue. Let me see if I can create simple and clean code for you to try MongoClient on it. I am really afraid MongoClient may cause issues with heavy concurrency (like 50+ simultaneous users).

PS - the driver is great!

christkv

unread,
Dec 19, 2012, 6:33:40 AM12/19/12
to node-mong...@googlegroups.com
you would have to supply an actual example of the code you are using to know where the problem is. most people do the mistake of opening up a new db connection on every incoming request. one needs to open the connection once and reuse the db object across all incoming requests.
Message has been deleted

Jose Tomas Rosales

unread,
Aug 29, 2013, 9:50:54 PM8/29/13
to node-mong...@googlegroups.com
but how do you reuse the db object if it is an async function
var MongoClient = require('mongodb').MongoClient
    , format = require('util').format;    

  MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
    if(err) throw err;

Mike Graf

unread,
Sep 25, 2013, 12:04:59 AM9/25/13
to node-mong...@googlegroups.com
You allow it to save into a variable outside of its context. (sorry if my vernacular isnt correct, i am newish to JS). At first i thought this had a race condition, but because it must be single threaded, i think its ok? (if connect(callback) is called a bunch of times before completing, will it create multiple new connections, saving into myDb multiple times?

Let me know what you think?
var MongoClient = require('mongodb').MongoClient;
var myDb;

/**
* will reuse connection if already created
*/
function connect(callback) {
if (myDb === undefined) {

MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
      if(err) { return callback(err)};
  myDb = db;
callback(null, db);
});
} else {
callback(null, myDb);
}

/**
* Use the db connection from our connect()
*/
function doCount(err, db) {
if (err) { return console.log('errrrrrrrr!'); }
db.collection('smurfs').count({'color':'red'}, function afterCount(err, count) {
if (err) { return console.log('merror xmas'); }
console.log('There was ' + count + ' smurf(s)');
});
}

connect(doCount);


Ok, HTH,
-- Mike

Всеволод Струкчинский

unread,
Feb 15, 2014, 2:15:28 AM2/15/14
to node-mong...@googlegroups.com
We abstracted code like this in npm module https://github.com/floatdrop/connect-once and https://github.com/floatdrop/express-mongo-db but got a strange behavior of connector - when we establish connection to mongo cluster (for example "host1,host2,host3") we drop host, which got connections from application. Our cached db connection now broken and it not try to reestablish connection to another host in list. What should we do to force connection try other host on timeout errors?

среда, 25 сентября 2013 г., 10:04:59 UTC+6 пользователь Mike Graf написал:

Mark Thien

unread,
Apr 18, 2014, 1:27:49 PM4/18/14
to node-mong...@googlegroups.com
Hi Mike,

Do you know how to add authentication to this code? like

client.authenticate('test', 'test', function(err, success) {

I tried to search around but just can't find any code that use authentication.

Cheers,
Mark

Mike Graf

unread,
Apr 18, 2014, 1:57:22 PM4/18/14
to node-mong...@googlegroups.com
use the URL for auth:
expanding on the example in the docs:
MongoClient.connect("mongodb://user1:pw1@localhost:30000,user2:pw2:localhost:30001/integration_test_?w=0&readPreference=secondary", function(err, db) {



--
You received this message because you are subscribed to a topic in the Google Groups "node-mongodb-native" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-mongodb-native/mSGnnuG8C1o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-mongodb-na...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mark Thien

unread,
Apr 18, 2014, 11:58:03 PM4/18/14
to node-mong...@googlegroups.com
ok thanks a lot Mike. Cheerio :-)
To unsubscribe from this group and all its topics, send an email to node-mongodb-native+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages