MongoClient initialization fails with secondary read preference and invalid replica set tag set value

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Works as Designed
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Not Needed
    • None
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      A MongoClient instance fails to initialize successfully when the Read Preference is set to either secondary or nearest, and a Replica Set Tag Set is specified that doesn't currently exists.

      Tested using:

      • Node.js driver v5.7.0
      • mongosh v1.10.2
      • Connection string of mongodb://localhost:27017/?replicaSet=replset&readPreference=secondary&readPreferenceTags=nodeType:ANALYTICS&serverSelectionTimeoutMS=2000

      To validate this behavior, spin up a PSS using mlaunch (MongoDB Server 7.0 used, but this shouldn't be a contributing factor):

      mlaunch init --replicaset --nodes 3
      

      Now test using the node REPL:

      node
      Welcome to Node.js v18.15.0.
      Type ".help" for more information.
      > var MongoClient = require('mongodb').MongoClient;
      undefined
      > await MongoClient.connect('mongodb://localhost:27017/?replicaSet=replset&readPreference=secondary&readPreferenceTags=nodeType:ANALYTICS&serverSelectionTimeoutMS=2000')
      Uncaught [MongoServerSelectionError: Server selection timed out after 2000 ms] {
        reason: TopologyDescription {
          type: 'ReplicaSetWithPrimary',
          servers: Map(3) {
            'localhost:27017' => [ServerDescription],
            'localhost:27018' => [ServerDescription],
            'localhost:27019' => [ServerDescription]
          },
          stale: false,
          compatible: true,
          heartbeatFrequencyMS: 10000,
          localThresholdMS: 15,
          setName: 'replset',
          maxElectionId: new ObjectId("7fffffff0000000000000001"),
          maxSetVersion: 1,
          commonWireVersion: 0,
          logicalSessionTimeoutMinutes: 30
        },
        code: undefined,
        [Symbol(errorLabels)]: Set(0) {}
      }
      

      Note this behavior does not reproduce using another driver:

      python
      Python 3.10.3 (main, Apr 11 2022, 06:49:33) [Clang 13.1.6 (clang-1316.0.21.2)] on darwin
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import pymongo
      >>> from pymongo import MongoClient
      >>> client = MongoClient('mongodb://localhost:27017/?replicaSet=replset&readPreference=secondary&readPreferenceTags=nodeType:ANALYTICS&serverSelectionTimeoutMS=2000')
      >>> db = client.admin
      >>> db.list_collection_names()
      ['system.version', 'system.keys']
      >>> print(pymongo.__version__)
      4.3.3
      

      If the replica set tag set is initialized and the test re-run the failures no longer reproduce.

      mongosh --quiet --eval 'conf = rs.conf(); conf.members[1].tags = { "nodeType": "ANALYTICS" }; rs.reconfig(conf);'
      {
        ok: 1,
        '$clusterTime': {
          clusterTime: Timestamp({ t: 1692188462, i: 2 }),
          signature: {
            hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
            keyId: Long("0")
          }
        },
        operationTime: Timestamp({ t: 1692188462, i: 2 })
      }
      
      node
      Welcome to Node.js v18.15.0.
      Type ".help" for more information.
      > var uri = 'mongodb://localhost:27017/?replicaSet=replset&readPreference=secondary&readPreferenceTags=nodeType:ANALYTICS';
      undefined
      > var MongoClient = require('mongodb').MongoClient;
      undefined
      > await MongoClient.connect(uri);
      <ref *1> MongoClient {
        _events: [Object: null prototype] {},
        _eventsCount: 0,
        _maxListeners: undefined,
        mongoLogger: MongoLogger {
          componentSeverities: {
            command: 'off',
            topology: 'off',
            serverSelection: 'off',
            connection: 'off',
            default: 'off'
          },
      [...]    
      

            Assignee:
            Unassigned
            Reporter:
            Alex Bevilacqua
            None
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: