Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-5865

When connecting to a 3.4 server, driver throws MongoTimeoutException from server selection

    • Type: Icon: Bug Bug
    • Resolution: Won't Fix
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: 5.5.0
    • Component/s: SDAM
    • None
    • Java Drivers
    • 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

      When connecting to a 3.4 or older server, the driver throws a MongoTimeoutException from server selection:

      Exception in thread "main" com.mongodb.MongoTimeoutException: 
      Timed out while waiting for a server that matches WritableServerSelector. 
      Client view of cluster state is {type=UNKNOWN, servers=[
       {address=localhost:27017, type=UNKNOWN, state=CONNECTING, 
        exception={com.mongodb.MongoSocketReadException: Prematurely reached end of stream}}]
      

      The excpected result is:

      Exception in thread "main" com.mongodb.MongoIncompatibleDriverException: 
      Server at localhost:27017 reports wire version 5, but this version of the driver requires at least 8 (MongoDB 4.2).
      

      The regression is caused by a change made in scope of JAVA-5831, where the method body of CommandMessage#isServerVersionKnown was changed from

      return settings.getMaxWireVersion() >= FOUR_DOT_ZERO_WIRE_VERSION;
      

      to

      return settings.getMaxWireVersion() != UNKNOWN_WIRE_VERSION;
      

       

      This method is used by CommandMessage to determine whether OP_MSG or OP_QUERY is used.  If it returns true, OP_MSG is used, otherwise OP_QUERY is used.

      We didn't expect that change to make a difference, but there is some code in InternalStreamConnectionInitializer#completeConnectionDescriptionInitialization that triggers this bug. The sequence of events is:

      1. DefaultServerMonitor opens a new connection.
      2. isMaster command is sent. Because maxWireVersion is not yet known, OP_QUERY is used
      3. description.getConnectionDescription().getConnectionId().getServerValue()} is {{null}} because the connectionId field was only added to the handshake reply starting with the 4.2 server release. So the initializer sends a getlasterror command to the server, which (for reasons lost to history) is included in that command's reply. But because maxWireVersion is now known, OP_MSG is used to send the getlasterror command.
      4. Since the 3.4 server doesn't recognized OP_MSG, it has no way to respond, and so it just closes the connection and a MongoSocketReadException is thrown.
      5. That causes the server selection loop to continue until the server selection timeout is reached, after which a MongoTimeoutException is thrown with the message shown above.

      There are two potential fixes for this:

      1. The first is to revert the change to CommandMessage#isServerVersionKnown
      2. The second is to remove the code that sends a getlasterror command when the connection id not send in the handshake reply. We should do this anyway eventually, since now that 4.2 is the minimum server version that the driver supports we should never actually execute that code unless the server version is unsupported, in which case it has no value anyway.

      One path forward is to do the first one in a patch release and the second in a minor release. Or we can just do the second one, and then the first one is not needed.

            Assignee:
            Unassigned Unassigned
            Reporter:
            jeff.yemin@mongodb.com Jeffrey Yemin
            None
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: