Mongoose: DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead

Created on 25 Jun 2017  ·  158Comments  ·  Source: Automattic/mongoose

DeprecationWarning: open() is deprecated in mongoose >= 4.11.0, use openUri() instead, or set the useMongoClient option if using connect() or createConnection()

Mongoose 4.11.0, MongoDB 2.2.29, NodeJS 8.1.2

Most helpful comment

The easiest fix for this; "npm remove mongoose" then "npm install [email protected] --save" problem solved. Upgrading is not always the best option.

All 158 comments

+1 , I have no idea where to fix to get rid of that warning

The warning is for a code inside Mongoose actually, when connecting string has a replica set:

Mongoose.prototype.connect = function() {
  var conn = this.connection;
  if ((arguments.length === 2 || arguments.length === 3) &&
      typeof arguments[0] === 'string' &&
      typeof arguments[1] === 'object' &&
      arguments[1].useMongoClient === true) {
    return conn.openUri(arguments[0], arguments[1], arguments[2]);
  }
  if (rgxReplSet.test(arguments[0]) || checkReplicaSetInUri(arguments[0])) {
    return new MongooseThenable(this, conn.openSet.apply(conn, arguments));
  }

  return new MongooseThenable(this, conn.open.apply(conn, arguments));
};

@tinovyatkin

So then, this is a bug?

looks like a bug, can we workaround by adding useMongoClient: true to options (you may see a deprecation from MongoDB driver then but that doesn't throw)

Adding useMongoClient: true makes the message disappear, but then my documents simply stop loading. Haven’t debugged it deeper, but I would prefer to hear best practices first before I adapt my code.

My application also doesn't work with the workaround suggested above. It simply doesn't run MyModel.find method anymore and gives no error and no timeout.

The reason why "useMongoclient: true" option doesn't work for most of the cases is for that option, every mongoose connection-related object returns dummy object cause not able to access mongodb

I tried to use it like

const server = express();
mongoose.connect('mongodb://localhost/advisorDemoTestDB', { useMongoClient: true })
    .then(() => require('./db-init')(server))
    .catch(err => console.error(err));

but it doesn't work

Having same issue, even without replica sets.

Having same issue:

(node:4138) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0,
 use `openUri()` instead, or set the `useMongoClient` option if using `connect()` 
or `createConnection()`

Same...

After I added below code to my mongo connection, I can't query out anything now.
{useMongoClient: true}.
Any suggestions will be appreciate!!

+1 same with replica sets, no sharding

+1

+1

+1

+1

+1

+1

+1

The easiest fix for this; "npm remove mongoose" then "npm install [email protected] --save" problem solved. Upgrading is not always the best option.

+1

+1

I get 2 messages:

(node:9260) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0,
use `openUri()` instead, or set the `useMongoClient` option if using `connect()`
or `createConnection()`

Server started on port 3000

Db.prototype.authenticate method will no longer be available in the next major
release 3.x as MongoDB 3.6 will only allow auth against users in the admin db
and will no longer allow multiple credentials on a socket. Please authenticate
using MongoClient.connect with auth credentials.

The first error appeared in 4.11.0. The second error also appeared in the previous version of Mongoose.

plhosk, the second one should have been fixed in 4.11 but looks like it's still there, for me too.

+1

+1 sadly.

Installed 4.10.8 without issues. Please consider changing npm install mongoose --save to default to 4.10.8 until 11 is stable.

+1

+1

+1

+1

I also found this issue too.
__Node version__: v6.10.0

__MongoDB__ emvironment: (I ran on the latest version of Mongo docker container)

2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] db version v3.4.5
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] git version: 520b8f3092c48d934f0cd78ab5f40fe594f96863
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1t  3 May 2016
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] allocator: tcmalloc
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] modules: none
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] build environment:
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten]     distmod: debian81
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten]     distarch: x86_64
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten]     target_arch: x86_64
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] options: { security: { authorization: "enabled" } }

My connection configuration:

var dbURL = `mongodb://${dbHost}:${dbPort}/${dbName}?authSource=admin`;
var dbAuth = { 
    useMongoClient: false
    user: dbUser,
    pass: dbPass
}
mongoose.connect(dbURL, dbAuth);

When I use useMongoClient to be false. Mongoose show following warnings:

(node:7868) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`
Express server listening on port 3222 in development mode
Db.prototype.authenticate method will no longer be available in the next major release 3.x as MongoDB 3.6 will only allow auth against users in the admin db and will no longer allow multiple credentials on a socket. Please authenticate u
sing MongoClient.connect with auth credentials.

But it work just fine.

However, when I set it to true, I found this error:

Unhandled rejection MongoError: not authorized on users to execute command { listIndexes: "sessions", cursor: {} }
    at Function.MongoError.create (<my project path>\node_modules\mongoose\node_modules\mongodb-core\lib\error.js:31:11)
    at queryCallback (<my project path>\node_modules\mongoose\node_modules\mongodb-core\lib\cursor.js:212:36)
    at <my project path>\node_modules\mongoose\node_modules\mongodb-core\lib\connection\pool.js:469:18
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

I also try to remove authSource=admin from connection URL too, but it still doesn't work

(node:451) DeprecationWarning: open() is deprecated in mongoose >= 4.11.0, use
openUri() instead, or set the useMongoClient option if using connect() or createConnection()
Db.prototype.authenticate method will no longer be available in the next major re
lease 3.x as MongoDB 3.6 will only allow auth against users in the admin db and w
ill no longer allow multiple credentials on a socket. Please authenticate using M
ongoClient.connect with auth credentials.

I get this issue with mongoose version 4.11.0 and MongoDB version 3.4.5

+1

+1

Use

mongoose.createConnection(URI)

@nandofalcao When using:

  • mongoose.createConnection (URI);
  • mongoose.connect (URI, {useMongoClient: true});

Apparently I can not save new records.

let userSchema = mongoose.Schema({ name: String });
let User = mongoose.model('User', userSchema);
let joao = new User({ name: 'NewJoao ' });
joao.save((err) => err ? throw err : console.log('User created!'));//nothing happens

Adding polyglot tonight and +1 experiencing this.

// Load Mongoose
const mongoose = require('mongoose');
// import mongoose from 'mongoose' didn't give access to .connect()

// Use native Promises
mongoose.Promise = global.Promise;

// Connect database
export const Mongoose = new Promise((resolve, reject) => {
  const uri = `mongodb://${Singleton.currentConfig.databases.mongodb.host}/${Singleton.currentConfig.databases.mongodb.database}`;

  const options = {
    user: Singleton.currentConfig.databases.mongodb.user,
    pass: Singleton.currentConfig.databases.mongodb.password,
    server: {
      reconnectTries: Singleton.currentConfig.databases.mongodb.reconnectTries,
      reconnectInterval: Singleton.currentConfig.databases.mongodb.reconnectInterval,
      socketOptions: {
        keepAlive: Singleton.currentConfig.databases.mongodb.keepAlive,
        connectTimeoutMS: Singleton.currentConfig.databases.mongodb.connectTimeoutMS
      },
    },
  };

  // Initiate document store
  mongoose.connect(uri, options)

  // Check for anomalies
  .then((connected) => {
    if (mongoose.connection.readyState !== 1) {
      reject(connected);
    }
    resolve(connected);
  })

  // Complete meltdown
  .catch((error) => {
    console.log(`MongoDB Connection Error: ${error}`);
    process.exit(0);
  });
});

+1

and i get the 2nd message:

[2017-06-27 16:14:23.702] [INFO] :: - Server started in port 2000

(node:1193) DeprecationWarning: open() is deprecated in mongoose >= 4.11.0, use openUri() instead, or set the useMongoClient option if using connect() or createConnection()

Db.prototype.authenticate method will no longer be available in the next major release 3.x as MongoDB 3.6 will only allow auth against users in the admin db and will no longer allow multiple credentials on a socket. Please authenticate using MongoClient.connect with auth credentials.

+1

+1

+1

+1

+1

Can somebody lock this to prevent useless +1's?

As a courtesy to subscribers of this thread, please stop replying with +1 because it generates useless email notifications. This is a not a forum. If you want to follow this thread, use the subscribe button on the right sidebar. You could also do some research yourself and contribute solutions.

I changed version back to 4.10.8 and it's working fine now.

Looks like ValYouW has a a potential fix to the document loading problem here: #5404

mongoose.connection.openUri('mongodb://127.0.0.1/camp_v12')

has anyone tried this? my deprecated warning disappeared when i use this, it was from the documentation

http://mongoosejs.com/docs/connections.html

@crisamdegracia that assumes you already have a connection

// Or, if you already have a connection
connection.openUri('mongodb://localhost/myapp', { /* options */ });

which we don't (at least me since I used to connect to mongodb using mongoose.connect method)

mongoose.connect(config.get('mongo'), {
  useMongoClient: true,
});

I could not find any document... Whats wrong?

+1

So after looking at the linked issue from @phased90 that explains that you can connect like so:

const mongoose = require('mongoose');

mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/test', {useMongoClient: true})
    .then(() => {
        let Cat = mongoose.model('Cat', {name: String});
        let kitty = new Cat({name: 'Zildjian'});

        kitty.save(err => {
            if (err) {
                console.log(err);
            } else {
                console.log('meow');
            }
        });
    })
    .catch(err => console.error(err));

I did a quick dive through the code and it appears that 4.11 returns MongooseThenable except for when the {useMongoClient: true} option is provided. In that instance it calls Connection.prototype.openUri which returns a new instance of Promise.ES6. Should that Connection.prototype.openUri call get wrapped in a MongooseThenable?

My apologies for the question, this is my first time looking at this codebase so I'm a bit unsure. But I would be happy to try and help provide a fix if I can get some clarification on if Moongoose.prototype.connect should always be returning an instance of MongooseThenable.

Be aware that using {useMongoClient: true} will cause Connection.prototype.openUri to be called, which doesn't trigger buffered commands that were created __before__ connecting to a DB due to #5404

+1

Sorry, things have been crazy, will take a look in a bit.

@varunjayaraman no need to be sorry mate. People can either wait, or try to fix it by themselves.

+1

So regarding the actual issue that was opened, the deprecation warning is not a bug, it's just a warning: mongoose is going to deprecate its current connection logic, so you should pass in the useMongoClient param. This can be found in the documentation

On a separate note, it looks like this was a backwards breaking change, hopefully this can be fixed in the next minor release (or maybe it isn't, I'm running on very little sleep here):

this would normally work (save for the useMongoClient part, which is new):

const mongoose = require('mongoose');
const co = require('co');
mongoose.Promise = global.Promise;
const GITHUB_ISSUE = `gh-5399`


exec()
  .then(() => {
    console.log('successfully ran program');
    process.exit(0);
  })
  .catch(error => {
    console.error(`Error: ${ error }\n${ error.stack }`);
  });


function exec() {
  return co(function*() {
    const db = mongoose.createConnection(`mongodb://localhost:27017/${ GITHUB_ISSUE }`, { useMongoClient: true })
    const schema = new mongoose.Schema({
      name: String
    });


    const Model = db.model('Model', schema);
  });
}

This seems to throw an error for me because db.model is no longer a function.

When using mongoose.model, it works:

const mongoose = require('mongoose');
const co = require('co');
mongoose.Promise = global.Promise;
const GITHUB_ISSUE = `gh-5399`


exec()
  .then(() => {
    console.log('successfully ran program');
    process.exit(0);
  })
  .catch(error => {
    console.error(`Error: ${error}\n${error.stack}`);
  });


function exec() {
  return co(function* () {
    const db = mongoose.connect(`mongodb://localhost:27017/${GITHUB_ISSUE}`, { useMongoClient: true })

    return db
      .then(() => {
        const schema = new mongoose.Schema({
          name: String
        });


        const Model = mongoose.model('Model', schema);

        return Model.create({ name: 'test' });
      })
      .then(doc => console.log(doc));

  });
}

@varunjayaraman I've just update Mongoose and use useMongoClient: true as you suggest, but I have an issue.
It doesn't support, according to the official Mongoose documentation, user, and pass options:

the options [user] is not supported
the options [pass] is not supported

And, yeah, failed to authen. :-1:

I'll try to add user and pass in the connection string instead.
It work when I add username and password into the connection string. Maybe you should update the documentation. 😐

@itpcc try to use 4.10.8 version is the best solution at this time.

npm remove mongoose
npm install [email protected] --save

Credit: @Chenz62

@CQBinh Thank you for your advice. I already read those comments about it.
However, I don't think using the older version is the best solution for now. And it can resolve by insert into connection string.
I just feel confused because it was mentioned in the document but it doesn't work. :/
BTW, I report as a new issue here

@varunjayaraman if db.model is no longer present, how would one handle multiple different mongoose connection with different models?

eg model1 and model2 attached to mongooseConnection1 and model3 and model4 attached to mongooseConnection2.

Previously this was done by calling mongoose.createConnection for each of the connections, and attaching the models to each of these return values.

Edit: Or is it still working in this case:

const conn = mongoose.createConnection(...);
const Model = conn.model('ModelName', schema);

+1

@boyce-ywr SERIOUSLY, another +1??? What's wrong with you people??
Post constructive comments, not stuff like that.

Regarding mongoose, it's not clear to me if the mongoose.connect() method will be replaced in future releases or not. Someone could explain please?

@simonemazzoni You are right, they're SPAMming us.

If you want to be included in the notifications for this thread, all you need to do is subscribe to it (there's a button at the top of the thread),

All your doing when you +1 is send everyone here an email saying

Hello I'm here!

We don't care, we're waiting for constructive comments and a solution.

Also why don't all of you +1's delete your posts out of this list, they're an eyesore and a pain in the rear to have to scroll past just to get to the real comments.

Like some people said before, the only "solution" is to go back to [email protected]_ ...
At least for now!

Looks like a bug, went back to [email protected] to solve the problem

Use mongoose.createConnection(...) instead of mongoose.connect(...)

Here's a complete working example of using [email protected] based on @diegoazh 's recommendation

const mongoose = require('mongoose')
mongoose.Promise = require('bluebird')  // optional, use this to get rid of 
                                        // the mpromise DeprecationWarning
const conn = mongoose.createConnection('mongodb://localhost/testDB')
const Schema = mongoose.Schema

const UserSchema = new Schema({
    username: String,
    email: String
})

const User = conn.model('User', UserSchema)
module.exports = User

@midnightcodr So we just drop connect and use createConnection instead?

@bertolo1988 just like ppl suggested on this issue, there are currently two workarounds

  1. Fall back to 4.10.8
  2. Use the new pattern if you like to stick with the new version
const conn = mongoose.createConnection(...)
const Model = conn.model(...)

I personally prefer the second solution.

Thanks!!!
solved by createConnection, and use that connection to make model ( instead of mongoose )

let mongoose = require('mongoose');

mongoose.Promise = global.Promise;

module.exports = mongoose;
const mongoose = require('./set-mongoose');
module.exports = mongoose.createConnection('mongodb://localhost/advisorDemoTestDB');

The new connection pattern requires some code changes, and depending on the size of your project that can mean a lot of time and maybe even architecture changes (given the fact that creating a model requires a connection).

It would have been great if the old connection model could wrap the new connection model.

There is a lot of post, so may I try to summarize:

  1. The warning is a deprecated warning, meaning, there is no rush. If we don't change anything it still gonna work as it always has, everything seems to be fine

  2. According the warning, connect() gonna be/has been modified and passing useMongoClient gonna be a must. But here is the possible bug/problem

  • connect('myurl', {useMongoClient: true}) => the document stop loading and it's not possible to write in the db

  • connect('myurl', {useMongoClient: false}) => seems to work fine but the warning is still displayed

Therefore the purpose of this issue is to correct the use of useMongoClient in case of the call of the method connect.

Agree?

Still, while a deprecation warning is indeed "just" warning, having that show up makes me wonder when it's actually going to be removed. If mongoose is following semver, it should still be there in the 4.x branch. Therefore, it should still work with backwards compatibility until 5.x is released.

Regarding the change itself, it's kind of annoying that I couldn't quickly find anything regarding this change except the one mentioned in the changelog. And even when you do change it, stuff still breaks and according to multiple people here, it's because of the .model() call.

Also, even the docs still show mongoose.connect() and mongoose.model(), which makes this matter even more confusing. The mongoose.connect() change is only mentioned under Connection pools, and not on other parts of this page. So the question remains, is this change a bug, or intended?

I don't know where this is going, but I've spent the better part of this weekend trying get a connection going to MongoDB's Atlas. The native mongodb driver was instantly up and running the CRUD stuff.

However trying to get mongoose going is a total nightmare. If I use createConnection with 4.11 the cluster connections get killed:

MongoError: connection 4 to cluster0-myshard.mongodb.net:27017 closed

Alternatively, I could set

useMongoClient: true

but then I get undefined on the connection.model

<info> atlas-api-test.js:65 (Test.testVendors) conn.model undefined

@Archomeda no plans to remove legacy connection behavior in 4.x, and 5.x is blocked on getting the new connection logic to a steady state. There are docs on the connection docs that 4.11.1 will improve and link to that should be helpful. Re: the model() call, if you specify useMongoClient: true, createConnection() will not return a connection, but rather a promise that resolves to a connection that you need to .then() on. Rationale is described here: https://github.com/Automattic/mongoose/issues/5404#issuecomment-312522539 Please feel free to voice any concerns about this on issue #5404 .

@mkastner looks like you're using createConnection(). With useMongoClient: true, createConnection() returns a promise that resolves to a connection. Please use await mongoose.createConnection() or mongoose.createConnection().then()

@peterpeterparker #5404 pointed out an issue with the new connection logic that will be fixed in 4.11.1, to be released within the next 24 hours.

@cosminn777 what architectural issues are you having? Please open up a separate issue to discuss them. The long-term plan is that in 5.x we will not support Node < 4, so everyone using mongoose will have native access to generators and/or async/await, so this change would be as easy as adding a yield or await statement.

@alanpurple the issue that you're referring to is the same as the one mentioned #5404 and will be fixed with 4.11.1.

@itpcc I opened up a separate issue to track #5432. For now, please put your username/password in the URI: var dbURL =mongodb://${dbUser}:${dbPass}@${dbHost}:${dbPort}/${dbName}?authSource=admin`.

In general, thanks everyone for your patience in trying this new behavior. I realize that switching over will cause some headache, which is why we hid this behavior behind a flag, but some changes coming down the pipe for MongoDB 3.6 necessitate a complete overhaul of mongoose's internal connection logic. I hope the new connection logic will lead to fewer mongoose-specific connection bugs in the long run, but please bear with us as we iron out the behavior and documentation. Your feedback is much appreciated.

As long as you're on 4.x your current connection logic will work, it will just print a warning. In the meantime, please feel free to report any issues you have in a separate github issue.

Just adopted the new method and it works great. Thanks everyone!

@vkarpov15 thanks for the clarifications.

As a FYI, the same deprecation warning is thrown with openSet as well (I am using a replica set).

So to summarise, it is safe to ignore this warning for now as it only relates to Mongoose's internal workings, and we could try to use useMongoClient but don't have to yet.

How stable is it do you reckon? Is it safe to use? I wouldn't want to spend 2 hours refactoring all our models and connection logic to find out that it's unusable in production still.

Is it possible to perhaps remove the deprecation warning until such a time that using the flag is stable and the recommended way to connect going forward? Or has that point been reached already?

@vkarpov15

But I am using async on createConnection. I've set up two tests against the db server. The first one is the native mongo-js canary test to make sure the url works and I can write and read:

tape('test connection via mongo native', async function testMongoConnection(t) {

  try {

    t.plan(1);
    let db = await MongoClient.connect(dbURL);
    await db.collection('users').insert({name: 'username'});
    let result = await db.collection('users').find({});
    let docs = await result.toArray();
    log.info('result', await result.toArray());
    t.equal(1, docs.length);
    db.collection('users').remove({});

    await db.close();

  } catch (err) {
  console.error(err)
  }
});

Result:

2017-07-04T09:00:34+0200 <info> atlas-api-test.js:28 (Test.testMongoConnection) result [ { _id: 595b3d1146734207bad88f9d, name: 'username' } ]
✔ should be equal

Succeeded by the mongoose test using mongoose createConnection with await:

tape('test connection via mongoose', async function testMongooseConnection(t) {

  try {
      let conn = await mongoose.createConnection(dbURL, {
        useMongoClient: true,
        /*
        // tried these settings too
        user: 'myUserName',
        pass: 'myPassword',
        connectTimeoutMS: 30000,
        rs_name: 'myReplSetName',
        ssl: true,
        auto_reconnect: true,
        */
      });

      let UserSchema = new mongoose.Schema({
        name: String,
      });

      let User = mongoose.model('User', UserSchema);
      let newUser = new User({name: 'username'});
      let createdUser = await newUser.save();

      // just ending test without validating any results
      t.end();

  } catch (err) {
    log.error(err);
  }

});

And it throws the following error:

/mypath/node_modules/mongodb/lib/replset.js:390 process.nextTick(function() { throw err; })
                                    ^
MongoError: connection 8 to cluster0-shard-00-02-c4nst.domain.com:27017 closed at Function.MongoError.create (/mypath/node_modules/mongodb-core/lib/error.js:29:11)
at Socket.<anonymous> (/mypath/node_modules/mongodb-core/lib/connection/connection.js:202:22)
at Object.onceWrapper (events.js:316:30)
at emitOne (events.js:115:13)
at Socket.emit (events.js:210:7)
at TCP._handle.close [as _onclose] (net.js:549:12)`

I might be terribly wrong here, but to me it doesn't look like an async/promise problem;

I`m using Mongo Atlas. When I use {useMongoClient: true}, My app will connect to the database successfully but the database does not a response to the application, way?

My code:
mongoose.connect(config.dbhost, {useMongoClient: true}, function(err){ if(err){ console.log(err); } else { console.log('connected to the database successfuly.'); } });

Just a notice for everyone because I haven't seen it mentioned here: 4.11.1 has been released and after a quick look it seems the buffering problem when using useMongoClient=true has been fixed. I'll test more tomorrow. Anyone else?

What is the final solution?

This worked for me (v.4.11.1):

database.js

mongoose.connect(databaseUri, { useMongoClient: true })
      .then(() => console.log(`Database connected at ${databaseUri}`))
      .catch(err => console.log(`Database connection error: ${err.message}`));

user.model.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({ ... });
const User = mongoose.connection.model('User', userSchema);

UPDATE

Referencing the connection may not be necessary when initializing your model (thanks, @kyrylkov @peterpeterparker):

user.model.js

const User = mongoose.model('User', userSchema);

Could someone explain briefly what exactly is { useMongoClient: true } for or what does that flag do?

I'm a little bit lost, what's the advantage of using it?

I mean, like I said before, I could live with the warning therefore I don't feel the rush to add this param.
Didn't find that much in the doc, thx in advance for clearing that up.

@Blackbaud-SteveBrush It does not work. I`m using Mongo Atlas. Why It does not work?

@Thinkdiff

Doesn't work how? It works for us on mLab and MongoDB Atlas with usual:

const User = mongoose.model('User', userSchema);

instead of:

const User = mongoose.connection.model('User', userSchema);

If I try to enable useMongoClient option with few hosts defined in the URI, It hangs and then throws error:
MongoError: no mongos proxy available at Timeout._onTimeout (/home/ubuntu/code/pss/node_modules/mongoose/node_modules/mongodb-core/lib/topologies/mongos.js:636:28) at ontimeout (timers.js:386:14) at tryOnTimeout (timers.js:250:5) at Timer.listOnTimeout (timers.js:214:5) name: 'MongoError', message: 'no mongos proxy available'
uri: mongodb://10.0.1.49,10.0.2.158,10.0.3.84/pss
options: { useMongoClient: true, autoReconnect: true, keepAlive: 300000, connectTimeoutMS: 30000 }

For anyone interested, here are the Mongoose docs on the useMongoClient parameter: http://mongoosejs.com/docs/connections.html#use-mongo-client

"Mongoose's default connection logic is deprecated as of 4.11.0...This deprecation is because the MongoDB driver has deprecated an API that is critical to mongoose's connection logic to support MongoDB 3.6, see this github issue for more details." Here's the GitHub issue: https://github.com/Automattic/mongoose/issues/5304

@Blackbaud-SteveBrush thx for pointing that our. So if I understand correctly

useMongoClient = true => activate new connection logic which will also work with Mongo 3.6
useMongoClient = false => default value. old connection logic < 4.11.0. the one which is deprecated.

right?

@Blackbaud-SteveBrush about your piece of code, in my case I don't use

const User = mongoose.connection.model('User', userSchema);

but

const User = mongoose.model('User', userSchema);

and it was still successful. thx

Mongoose works for me 4.10.8 :|

I've found that this is likely a bug with mongoose

problem went away after rolling back mongoose version

npm uninstall -save mongoose
npm install -save [email protected]

I have completely ignored this warning and everything is working as expected. Maybe, this the solution for now. Just ignore.

rolling back to 4.10.8 got my connection working again however i still get the error

Db.prototype.authenticate method will no longe against users in the admin db and will no long connect with auth credentials.

@peterpeterparker correct. Mongoose's current auth code will not work on mongodb 3.6 based on my understanding, so useMongoClient represents us trying to get ahead of this problem while maintaining backwards compatibility. As far as I know there is no scheduled release date for mongodb 3.6 yet, so switching over is not pressing.

@adamreisnz we've had a few bugs but really the new connection logic is a very thin wrapper around using the native driver's MongoClient.connect() function, which has been the preferred method for connecting to mongodb for a couple years now. Once your connection is established its the same mongodb driver logic maintaining the connection. useMongoClient should only affect initial connection.

@vkarpov15 thx a lot for the explanation and of course for the work, really appreciate it!

@vkarpov15 thanks, I'll give it a go and switch to using useMongoClient and see where it takes us.

const mongoose = require("mongoose");
const db = "mongodb://localhost/testaroo";

mongoose.connection.openUri(db);
mongoose.connection.once("open", function () {
console.log("connection established");
}).on("error", function (error) {
console.log(error);
})

--i use this and no errors found

var mongoose = require('mongoose');
mongoose.Promise = global.Promise;

var mongoDB = mongoose.connect('mongodb://your_database', {
    useMongoClient: true
});

mongoDB
    .then(function (db) {
        console.log('mongodb has been connected');
    })
    .catch(function (err) {
        console.log('error while trying to connect with mongodb');
    });

module.exports = mongoDB;

I use this and no errors found

@vitorbarros It worked for me. Thanks!

It works for me:
http://mongoosejs.com/docs/connections.html#use-mongo-client

I ran this quick test and it worked:

// index.js
const mongoose = require('mongoose')
mongoose.Promise = global.Promise;
const db = mongoose.createConnection(`mongodb://localhost/test`)

db.on('error', err => console.log(err))
db.once('open', () => {
  console.log(`Connected to Mongo at: ${new Date()}`)
  db.close(() => {
    console.log(`Disconnected from Mongo at: ${new Date()}`)
  })
})

then node index.js gives me:

Connected to Mongo at: Thu Jul 13 2017 22:54:50 GMT+0000 (UTC)
Disconnected from Mongo at: Thu Jul 13 2017 22:54:50 GMT+0000 (UTC)

Thank you all!

@vitorbarros your solution works! thanks.

I can confirm that with 4.11.3 replacing the connection logic with what @vitorbarros suggested removes the warnings and seems to work well 👍

There is no need to refactor model references as suggested earlier here in this thread.

@vitorbarros's solution is indeed the recommended way according to "The useMongoClient Option" documentation.

However, note that mongoose.Promise = global.Promise; will _not_ promisify the underlying Mongo driver. According to the "Promises for the MongoDB Driver" documentation, the promiseLibrary property should also be set in the options object of the connect method.

For example:

var mongoDB = mongoose.connect('mongodb://your_database', {
    useMongoClient: true,
    promiseLibrary: global.Promise
});

global.Promise would use the native promise engine. Naturally, it's also possible to use Bluebird or any other engine, e.g. promiseLibrary: require('bluebird')

@vitorbarros solution works for me. And also we need to use promiseLibrary like @boaz-amit said.
But which way is the best for using authentication data?
In URL

mongodb://[username:[email protected]]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

or better set user and password in options? I can't find right place for now.

This is only one way to authenticate?

And here is my solution. This also works even if first connect fails.

let firstConnectTimeout = null;
const mongoConnect = () => {
    const mongoDB = mongoose.connect('mongodb://localhost/test', {
        useMongoClient: true
    });

    mongoDB
        .then((db) => {
            clearTimeout(firstConnectTimeout);
        })
        .catch((err) => {
            firstConnectTimeout = setTimeout(mongoConnect, 5000);
        });
};

mongoConnect();

It has to be in url, the user / pass options no longer work with
useMongoClient true I found.

On Mon, Jul 17, 2017, 20:28 Andrey Prisniak notifications@github.com
wrote:

@vitorbarros https://github.com/vitorbarros solution works for me. And
also we need to use promiseLibrary like @boaz-amit
https://github.com/boaz-amit said.
But which way is the best for using authentication data? In URL
mongodb://[username:[email protected]
]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
or better set user and password in options? I can't find right place for
now.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Automattic/mongoose/issues/5399#issuecomment-315694642,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAd8Qup1YY4lhUhQccv2kLKtraARxvP0ks5sOxs_gaJpZM4OEnIt
.

@adamreisnz @aprisniak working on it, see #5419. In the meantime, please put the username and password in your URI: mongodb://user:pass@hostname:port/db

Also, I wrote a blog post about this option and why it is necessary: http://thecodebarbarian.com/mongoose-4.11-use-mongo-client.html

@vkarpov15 I am using user:pass in URI, but still have the warning.

For those who use mongoose with gridfs-stream:

const mongooseConnect = mongoose.connect(
    process.env.MONGODB_URI || process.env.MONGOLAB_URI,
    {
        useMongoClient: true
    }
)

let gfs
mongooseConnect.then(conn => {
    gfs = Grid(conn.db)
    /** Setting up GFS storage here */
})

May you guys add the missing connection option "useMongoClient" at typescript typings", and add typings back to this project instead to add typings packages.

I am not sure should I do something with this warning or not? It will be fixed, right?

I just add the useMongoClient in typings to make it work. @iamdubx

@FinalDes how? I added mongoose.connect(process.env.DATABASE, { useMongoClient: true }) but I still got the message. And I am using user:pass in URI

Better way to get rid of such problem is to use these two commands:
npm uninstall -save mongoose
npm install -save [email protected]

NB: [email protected] is the stable version.

How are you all handling your creating your Schema and Model as well as accessing them?

I've tried every fix in the thread. With the warning, everything works fine. Once I try useMongoClient: true or mongoose.createConnection it gets rid of the warning and I can connect to the db, however any code that attempts to access the model fails to trigger. There are no errors, the code just never runs.

@iamdubx
just missing the typings, so when run with "noImplicitAny": true , will not have error

import mongoose = require("mongoose");
import dotenv = require("dotenv");
dotenv.config();
mongoose.Promise = global.Promise;
const MONGO_URI=`mongodb://${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DB}`;
mongoose.connect(MONGO_URI, {
useMongoClient: true,
});

@FinalDes what are you referring to? What missing typings? I have the same code above and have an error.

I have encountered the same problem with @Snow-Okami

  1. const mongoDB = mongoose.connect(config.database, { useMongoClient: true });
    This gets rid of the warning and connects to the db. However, everthing that attempts to access the model fails (get/post). No error returns.
  2. const mongoDB = mongoose.connect(config.database, function(){ useMongoClient: true });
    And this gives those two warnings, but everything other than that works fine.

Please at least give backward compatiblity our production build server fails.
feature updation is good but don't change method signature or call.

@Nikunjksanghavi It's only a warning, nothing should be failing.

@iamdubx what kind of error?

@FinalDes deprecation error, what else we are talking about in this topic?

This worked for me: (v.4.11.4)

const MONGO_URI = process.env.MONGO_URI
const mongoose = require('mongoose');

// Use your own promis library
mongoose.Promise = require('bluebird');

// connect to mongo, use Mongo Client
mongoose.connect(MONGO_URI, {useMongoClient: true})
  .then(({db: {databaseName}}) => console.log(`Connected to ${databaseName}`))
  .catch(err => console.error(err));

const poemSchema = mongoose.Schema({
    name: String,
    text: String
});

const Poem = mongoose.model('Poem', poemSchema);

const insertPoem = poem =>
  (new Poem(poem)).save( (err, newPoem) => 
    console.log(err || newPoem));

insertPoem({name: 'poemName', text: 'this is a poem'})

// DB connection
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/login_register', {
useMongoClient: true
})
.then(() => console.log('connection succesful'))
.catch((err) => console.error(err));
// DB connection end

This doesn't work for me. I still have console warning. And no clear explanation provide.

Mongoose is horrible. Also worst documentation site that I saw in libraries that so popular. What a shame!

Now I am thinking to switching to RethinkDB. Linux Foundation - this is serious.
Also Postgre awesome.

Mongo - very, very shame.

@iamdubx did you try my solution above? Could you paste the warning on this? Maybe I could help out :)

@iamdubx can post your warning message?

@FinalDes @shams-ali I posted before, it's the same deprecation error as topic has. The one this topic is about!

(node:3304) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/connections.html#use-mongo-client
Server listening on port: 7777
Db.prototype.authenticate method will no longer be available in the next major release 3.x as MongoDB 3.6 will only allow auth against users in the admin db and will no longer allow multiple credentials on a socket. Please authenticate using MongoClient.connect with auth credentials.

@iamdubx interesting, that's the same warning I had and the above solution I posted seemed to fix it for me. Could you paste your updated code that isn't working?

This is what worked for me:

// ES6 promises
mongoose.Promise = Promise;

// mongodb connection
mongoose.connect("mongodb://localhost:27017/sandbox", {
  useMongoClient: true,
  promiseLibrary: global.Promise
});

var db = mongoose.connection;

// mongodb error
db.on('error', console.error.bind(console, 'connection error:'));

// mongodb connection open
db.once('open', () => {
  console.log(`Connected to Mongo at: ${new Date()}`)
});

@afoke is works thanks

@FinalDes You're welcome mate.

This is my new workflow, trying to be compliant with the warnings and deprecations:

// db.js
const model = require('./model');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;


async function db(uri) {
  const con = await mongoose
    .createConnection(uri, {
      useMongoClient: true,
    });

  const {User} = model(con);

  // do something with User
  ...

  // the interface for the server
  return {
    create: params => User.create(params),
    ...
  };
}


module.exports = db;

And now the models module returns a function of connection

// model.js
const {Schema} = require('mongoose');


const UserSchema = new Schema({
  name: String,
  age: Number,
});

// Other Schemas
...

module.exports = con => ({
  User: con.model('User', UserSchema),
  ...
});

Any official guidelines on the subject?

@iamdubx Sounds like you don't understand the difference between a warning and an error.

The warning in question does not break anything, but warns the user of something that will be removed in the next major release.

Mongoose is horrible.

So keep in mind, you're having this reaction to the developers warning you ahead of time before they remove a feature. I'd also urge you to remember that you're using this free of charge, so maybe give the developers the benefit of the doubt before you throw a tantrum

@chrisdothtml

The warning in question does not break anything, but warns the user of something that will be removed in the next major release.

It does pollute tests and console which is mildly annoying.

Mongoose is horrible. Also worst documentation site that I saw in libraries that so popular. What a shame!

He is being impolite which is also mildly annoying but he makes a very valid point in regards to Mongoose documentation. It is not the worst documentation ever but it could really be improved.

The fact that mongoose forwards the mongo client API. which works in a very different way, makes Mongoose usage and documentation confusing.

A possible solution for this would be:

  • stop doing it
  • remove the documentation for the Mongo client methods
  • provide a way to share connection between the official client and Mongoose

I would also suggest improving docs searchability by breaking it in several pages and giving more insight to new users about on what is Mongoose actually doing to achieve some of the results.

I had this error, but it disappeared after I added {useMongoClient: true} option.
I use Debian 9, testing version, with MongoDb ver. 3.2.11 and mongoose ver. 4.10.4.
I have 'Connected to MongoDB' message (view code in Typescript below), everything works perfectly.

(< any >mongoose).Promise = global.Promise;
mongoose.connect(process.env.MONGODB_URI, {useMongoClient: true});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('Connected to MongoDB');
setRoutes(app);
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, '../public/index.html'));
});
app.listen(app.get('port'), () => {
console.log('MyApp listening on port ' + app.get('port'));
});
});

Just uninstall the current mongoose version which you have and install the lower version npm install [email protected] --save . No need to do anything else this will definately work for you.

mongoose.connect(database.host, { useMongoClient: true });

This solved my problem. But I had another warning coming up after I made this change.

DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

This code solves all deprecation warnings:
```javascript
mongoose.Promise = global.Promise;
mongoose.connect(uri, {
keepAlive: true,
reconnectTries: Number.MAX_VALUE,
useMongoClient: true
});
````
More info by the link -> http://mongoosejs.com/docs/connections.html#use-mongo-client

@bricss Fantastic! Thanks!

@bricss You made my day.

someone earned a hero badge...

edit: @bricss It eliminated the deprecation warnings for me, but I couldn't retrieve data from my mLab sandboxes. It may be because they are using an older version of MongoDB. I'll try to check into it later.

edit: @bricss It's now working correctly with the latest mongoose 4.11.9 and a connection to Cosmos DB on Azure.

@bricss : Nicely done Bricks! It worked for me even though I'm using a really old version of mongodb in my local :+1:

@bricss Awesowe! But you might consider putting a smaller number for "reconnectTries". You don't want to spend the whole day reconnecting if there is an issue with your DB.

@afoke 's solution worked for me, only when i explicitly declare the db in the connection string i.e. mongodb://localhost:27017/test but not mongodb://localhost:27017

May I create connection to 2 DB's without this warning? I need to use my models with different DB's.

Using mongoose v^4.11.6 , when added useMongoClient the warning dispeared.

const uri = "http://blablabla.blo/blaDB"; mongoose.Promise = global.Promise; mongoose.connection.on('error', (err) => { console.error(Mongoose connection error: ${err}`);
process.exit(1);
});
mongoose.connect(uri, {useMongoClient: true});

 // load models
 require('./model1');
 // ...
 require('./modelN');`

connecting to database in this way solves the problem:
mongoose.connect(url,{user:'username',pass:'mypassword',useMongoClient:true});

Will these errors cause problems , for example in security?

No more "deprecated" warning pops up if I use this syntax 🎉

mongoose.connection.openUri('mongodb://localhost/test')
  .once('open', () => console.log('Good to go !'))
  .on('error', (error) => {
    console.warn('Warning', error);
  });

I faced the same deprecation warning as below:
(node:2300) DeprecationWarning: open() is deprecated in mongoose >= 4.11.0, use openUri() instead, or set the useMongoClient option if using connect() or createConnection(). See http://mongoosejs.com/docs/connections.html#use-mongo-client

Solution

I tried the following and it works fine. Gives no deprecation warnings.

mongoose.connect('mongodb://127.0.0.1:27017/your-database-name', { useMongoClient: true, promiseLibrary: global.Promise });

Hope this will help everyone facing this issue.

I have the same issue but when trying to connect to Mongo Atlas service it just not connect with {useMongoClient:true} option and without it the connection is no longer executed.

Anyone with the same issue?

I had solved my problem by just change the mongoose.connect to mongoose.createConnection

mongoose.createConnection(config.uri, (err) => {
if (err) {
console.log('Could NOT connect to database: ', err);
} else {
console.log('Connected to database: ' + config.db);
}
});

I solved this problem like that (Mongoose 4.12.0, NodeJS - 7.10.1)

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/books_exchange', {
  useMongoClient: true,
  promiseLibrary: require('bluebird')
}).then(() => {
  var userSchema = new mongoose.Schema({
    name: String,
    password: String
  });
  var User = mongoose.model('User', userSchema);

  var person = new User({
    name: "John",
    password: "qwerty"
  });

  person.save().then(() => {
    console.log('Data saved');
  }).catch(e => {
    console.log(e);
  });
}).catch(e => {
  console.log('Error while DB connecting');
  console.log(e);
});
Was this page helpful?
0 / 5 - 0 ratings