Azure Cosmos DB MongoNetworkError when local development

Here is the correct connection string to connect to Azure Cosmos DB

Note that this is not enough if you'd like to connect from your developer machine (http://localhost:3000 or http://127.0.0.1:3000). A new instance of Azure Cosmos DB has its firewall enabled for selected networks by default. You will have to add your local IP to the range of the selected network of IPs so to access it.

var mongoose = require('mongoose');

//...

mongoose.Promise = global.Promise;

mongoose.connect("mongodb://<YOUR_COSMOS_DB_DOMAN>.mongo.cosmos.azure.com:10255/<YOUR_DB_NAME>[email protected]<[email protected]", {
  auth: {
    user: '<YOUR_COSMOS_DB_USERNAME>',
    password: '<YOUR_COSMOS_DB_KEY>'
  },
  useNewUrlParser: true,
  useUnifiedTopology: true
})
.then(() => console.log('Connection to CosmosDB successful'))
.catch((err) => console.error(err));
Azure-CosmosDb-Firewall-ID

MongoNetworkError: failed to connect to server [yourdb.mongo.cosmos.azure.com:10255] on first connect

My first attempt to access the Azure Cosmos DB from my localhost resulted in the error below, and it took me some time to figure out that it is the firewall.

MongoNetworkError: failed to connect to server [yourdb.mongo.cosmos.azure.com:10255] on first connect [MongoNetworkError: connection 0 to yourdb.mongo.cosmos.azure.com:10255 closed
    at TLSSocket.<anonymous> (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connection.js:372:9)
    at Object.onceWrapper (events.js:300:26)
    at TLSSocket.emit (events.js:210:5)
    at net.js:659:12
    at TCP.done (_tls_wrap.js:481:7) {
  name: 'MongoNetworkError',
  [Symbol(mongoErrorContextSymbol)]: {}
}]
    at Pool.<anonymous> (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\topologies\server.js:438:11)
    at Pool.emit (events.js:210:5)
    at C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\pool.js:561:14
    at C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\pool.js:994:11
    at callback (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connect.js:97:5)
    at C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connect.js:124:7
    at _callback (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connect.js:349:5)
    at Connection.errorHandler (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connect.js:365:5)
    at Object.onceWrapper (events.js:300:26)
    at Connection.emit (events.js:210:5)
    at TLSSocket.<anonymous> (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connection.js:370:12)
    at Object.onceWrapper (events.js:300:26)
    at TLSSocket.emit (events.js:210:5)
    at net.js:659:12
    at TCP.done (_tls_wrap.js:481:7) {
  name: 'MongoNetworkError',
  [Symbol(mongoErrorContextSymbol)]: {}
}

MongoNetworkError, AuthenticationFailed with 'Invalid key,' was the first caveat I have faced.

The 'Invalid key' is an issue with the connection string issue. If I open the Azure portal, then go to the Cosmos DB instance, then go to the Quick Start section and select Node.js on choose platform, then I will see two ways of specifying the secret (or the password). What worked for me with Mongoose == 5.9.5 was the string that is not encoded i.e., Node.js 2.2 driver example.

MongoNetworkError: failed to connect to server [yourdb.mongo.cosmos.azure.com:10255] on first connect [MongoError: Invalid key
    at C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\auth\auth_provider.js:46:25
    at C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\auth\scram.js:240:11
    at _callback (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connect.js:349:5)
    at Connection.messageHandler (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connect.js:378:5)
    at Connection.emit (events.js:210:5)
    at processMessage (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connection.js:384:10)
    at TLSSocket.<anonymous> (C:\Projects\yourdb\nodeapp\node_modules\mongodb\lib\core\connection\connection.js:553:15)
    at TLSSocket.emit (events.js:210:5)
    at addChunk (_stream_readable.js:309:12)
    at readableAddChunk (_stream_readable.js:290:11)
    at TLSSocket.Readable.push (_stream_readable.js:224:10)
    at TLSWrap.onStreamRead (internal/stream_base_commons.js:182:23) {
  ok: 0,
  errmsg: 'Invalid key',
  code: 18,
  codeName: 'AuthenticationFailed',
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {}
}]

MongooseError, [MongooseServerSelectionError]: connection to 255.255.255.255:10255 closed

This look has to do with the use of UnifiedTopology. This property has to be set to true to allow Mongoose to discover the database, I guess. I think that setting the property to true sorted that error for me.

MongooseError [MongooseServerSelectionError]: connection <monitor> to 255.255.255.255:10255 closed
    at new MongooseServerSelectionError (C:\Projects\yourdb\nodeapp\node_modules\mongoose\lib\error\serverSelection.js:22:11)
    at NativeConnection.Connection.openUri (C:\Projects\yourdb\nodeapp\node_modules\mongoose\lib\connection.js:823:32)
    at Mongoose.connect (C:\Projects\yourdb\nodeapp\node_modules\mongoose\lib\index.js:333:15)
    at Object.<anonymous> (C:\Projects\yourdb\nodeapp\app.js:21:10)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
    at Module.load (internal/modules/cjs/loader.js:815:32)
    at Function.Module._load (internal/modules/cjs/loader.js:727:14)
    at Module.require (internal/modules/cjs/loader.js:852:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (C:\Projects\yourdb\nodeapp\bin\www:7:11)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
    at Module.load (internal/modules/cjs/loader.js:815:32)
    at Function.Module._load (internal/modules/cjs/loader.js:727:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10) {
  message: 'connection <monitor> to 104.45.144.73:10255 closed',
  name: 'MongooseServerSelectionError',
  reason: TopologyDescription {
    type: 'Single',
    setName: null,
    maxSetVersion: null,
    maxElectionId: null,
    servers: Map {
      'yourdbprod.mongo.cosmos.azure.com:10255' => [ServerDescription]
    },
    stale: false,
    compatible: true,
    compatibilityError: null,
    logicalSessionTimeoutMinutes: null,
    heartbeatFrequencyMS: 10000,
    localThresholdMS: 15,
    commonWireVersion: null
  },
  [Symbol(mongoErrorContextSymbol)]: {}
}

Another caveat is that I manually created the database

If you experience issues connecting to your database, this is something you can do in advance. Because the connection string requires your database to be presend, I am not sure how it will behave if you do not have one pre-provisioned.

Azure-CosmosDb-Data-Explorer-New-Database

Conclusion

Pay attention to security, do not add a way to many exceptions to there. In general, a developer can use a local instance of mongo DB until the app is ready to be deployed and hooked to Azure Cosmos DB. Sometimes there are scenarios where a developer has to connect to the remote instance. In that case, beware of the firewall settings.

Comments

Comments are disabled.