Skip to content

Docsp 29488 - Add Connection Troubleshooting Guide #690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 20, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
325 changes: 325 additions & 0 deletions source/connection-troubleshooting.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
.. _node-connection-troubleshooting:

==========================
Connection Troubleshooting
==========================

.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol

This page offers potential solutions to issues you might encounter when
using the {+driver-long+} to connect to a MongoDB deployment.

.. note::

This page addresses only connection issues. If you encounter any other issues
with MongoDB or the driver, visit the following resources:

- The :ref:`Frequently Asked Questions (FAQ) <node-faq>` for the
{+driver-short+}
- The :ref:`Issues & Help <node-issues-help>` page, which has
information about reporting bugs, contributing to the driver, and
finding additional resources
- The `MongoDB Community Forums <https://community.mongodb.com>`__ for
questions, discussions, or general technical support

Connection Error
~~~~~~~~~~~~~~~~

The following error message is a general message indicating that the driver
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question:

Is this directly related to an issue with being able to resolve the address? If so, I think it would be great to explain that detail since the issue could come from a temporary/intentional DNS change which could help some people find the culprit of the issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not. While that is one of the reasons this error can be generated, this is also a catch all that gets generated if there is not a more specific message to filter up. Since this can be generated for a number of reasons as a general catch-all, I can't go into detail for all the reasons it can be generated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
I think it would make sense then to omit "general" and add an explanation that the error has many potential causes to avoid confusion about what "general message" means.

Maybe the adjective "generic" might fit, but would avoid that for any potential negative connotation, unless describing the programming term "generics/generic types".

cannot connect to a server on the specified hostname or port:

.. code-block:: none
:copyable: false

Error: couldn't connect to server 127.0.0.1:27017

The following sections describe methods that may help resolve the issue.

.. _node-troubleshooting-connection-string-port:

Check Connection String
-----------------------

Verify that the hostname and port number in the connection string are both
accurate. In the sample error message, the hostname is ``127.0.0.1`` and the
port is ``27017``. The default port value for a MongoDB instance is
``27017``, but you can configure MongoDB to communicate on another port.

.. _node-troubleshooting-connection-firewall:

Configure Firewall
------------------

Assuming that your MongoDB deployment uses the default port, verify that port
``27017`` is open in your firewall. If your deployment uses a different port,
verify the correct port is open in your firewall.

.. warning::

Do not open a port in your firewall unless you are sure that it's the port
used by your MongoDB instance.

ECONNREFUSED Error
~~~~~~~~~~~~~~~~~~

If the connection is refused when the driver attempts to connect to the MongoDB
instance, it generates this error message:

.. code-block:: none
:copyable: false

MongoServerSelectionError: connect ECONNREFUSED ::1:27017

The following sections describe methods that may help resolve the issue.

Start mongod in IPV6 Mode
-------------------------

Beginning with version 17, Node.js defaults to using ``IPV6``. You can start
your ``mongod`` in ``IPV6`` mode with
:manual:`the --ipv6 flag </reference/program/mongod/#std-option-mongod.--ipv6>`,
or setting the ``net.ipv6`` option to ``true``
:manual:`in your configuration file </reference/configuration-options/#mongodb-setting-net.ipv6>`.

.. code-block:: sh
:caption: Starting mongod with the --ipv6 flag

mongod --ipv6

.. code-block:: yaml
:caption: Setting the net.ipv6 option in the configuration file

net:
ipv6: true

Use IPV4 with Your Mongo Client
-------------------------------

Beginning with version 17, Node.js defaults to using ``IPV6``. You can
explicitly use ``IPV4`` with your client by specifying ``family: 4`` as an
`option to your MongoClient <{+api+}/interfaces/MongoClientOptions.html#family>`__.

.. code-block:: js

const client = new MongoClient(uri, {
family: 4,
});

ECONNRESET Error
~~~~~~~~~~~~~~~~

If the connection is reset when the driver calls ``client.connect()``, it
generates this error message:

.. code-block:: none
:copyable: false

MongoServerSelectionError: connect ECONNRESET ::1:27017

The following section describes a method that may help resolve the issue.

Increase Number of File Descriptors
-----------------------------------

In most operating systems, each connection is associated with a `file
descriptor
<https://www.computerhope.com/jargon/f/file-descriptor.htm>`_. There is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue:

  1. Avoid linking to a third party site that isn't the official informational source, and on which we cannot reasonably guarantee the content.

  2. I think this section also refers to both "connections" and "sockets" and it is confusing whether they are referring to something similar or different.
    "each connection is..."
    "connect with a pool size of 5000 sockets".

Suggestion:

  1. I think a one sentence description of the term "file descriptor" would be sufficient to build an understanding, and the user could then search for it themselves if they needed more context.

  2. Define both "connection" and "socket" or try to use only one of these terms.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the link was approved since this was a copy from the old FAQ (https://www.mongodb.com/docs/drivers/node/current/faq/#what-can-i-do-if-i-m-getting--econnreset--when-calling--client.connect----) and moved over (as opposed to completely new authored content). I will remove the link when I reword the section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For context:
The old FAQ was a copy and paste from the old GitHub Pages docs and skipped content review. Most of the initial Node.js driver docs (on MongoDB domain) content was also created prior to our team's decision to enforce rules in the style guide.

I think we want to keep in-line with style guide best practices to Use MongoDB-Domain Links When Possible.

typically a limit set by the operating system on the number of file
descriptors used by a single process. An ``ECONNRESET`` error can occur
if the connection pool size surpasses the limit of ``file descriptors``.

Consider the following operation:

.. literalinclude:: /code-snippets/faq/econnresetWithClientConnect-example.js
:language: javascript
:linenos:

If this operation causes an ``ECONNRESET`` error, you may have run into
the ``file descriptor`` limit for your Node.js process. In that case you
must increase the number of ``file descriptors`` for the Node.js process. On
MacOS and Linux you do this with the `ulimit
<https://ss64.com/bash/ulimit.html>`_ shell command.

.. code-block:: sh

ulimit -n 6000

This sets the maximum number of ``file descriptors`` for the process to
6000, allowing Node.js to connect with a pool size of 5000 sockets.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
I think file descriptors are used for more than just connections, so maybe there is no guarantee. I think it is sufficient to draw the connection between file descriptors and connections, perhaps earlier in the description.

E.g.
"The driver needs to use file descriptors to reference each connection in its connection pool."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:

I wasn't able to find information in this section that referenced the connection pool. I think that could be important for the user to understand how setting a maxPoolSize above the file descriptor limit could initially work, but then error out when the number of connections in the pool grows.


Authentication Error
~~~~~~~~~~~~~~~~~~~~

The {+driver-short+} can fail to connect to a MongoDB instance if
the authorization is not configured correctly. In these cases, the driver raises
an error message similar to one of the following messages:

.. code-block:: none
:copyable: false

Command failed with error 18 (AuthenticationFailed): 'Authentication
failed.' on server localhost:27017.

.. code-block:: none
:copyable: false

connection() error occurred during connection handshake: auth error:
sasl conversation error: unable to authenticate using mechanism
"SCRAM-SHA-256": (AuthenticationFailed) Authentication failed.

The following sections describe methods that may help resolve the issue.

.. _node-troubleshooting-connection-string-auth:

Check Connection String
-----------------------

An invalid connection string is the most common cause of authentication
issues when attempting to connect to MongoDB.

.. tip::

For more information about connection strings,
see :ref:`Connection URI <node-connection-uri>` in the Connection Guide.

If your connection string contains a username and password, ensure that they
are in the correct format.

.. note::

If the username or password includes any of the following characters, they
must be `percent encoded <https://tools.ietf.org/html/rfc3986#section-2.1>`__:

.. code-block:: none

: / ? # [ ] @

When connecting to a replica set, you should include all of the hosts
in the replica set in your connection string. Separate each of the hosts
in the connection string with a comma. This enables the driver to establish a
connection if one of the hosts is unreachable.

.. _node-troubleshooting-connection-admin:

Verify User Is in Authentication Database
-----------------------------------------

To successfully authenticate a connection by using a username and password,
the username must be defined in the authentication database. The default
authentication database is the ``admin`` database. To use a different database
for authentication, specify the ``authSource`` in the connection string. The
following example instructs the driver to use ``users`` as the authentication
database:

.. code-block:: javascript
:copyable: true

const { MongoClient } = require("mongodb");
const uri = "mongodb://<username>:<password>@<hostname>:<port>/?authSource=users";
const client = new MongoClient(uri);

Error Sending Message
~~~~~~~~~~~~~~~~~~~~~

When the driver fails to send a command after you make a request,
it often displays the following general error message:

.. code-block:: none
:copyable: false

com.mongodb.MongoSocketWriteException: Exception sending message

The following sections describe methods that may help resolve the issue.

Check Connection String
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question:
I'm not certain how this is related to failing to send a command. If they did not get a connection-related error previously, what circumstances could make this error happen that are related to the connection string? Perhaps there are some options on the connection string that might cause this? If so, could those be included here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this can happen if the user does not have the appropriate permissions, so the thought is to make sure the user in the connection string is connect. I will specify in the content.

-----------------------

Verify that the connection string in your app is accurate. For more information
about verifying your connection string, see
:ref:`Connection Error <node-troubleshooting-connection-string-port>`
and :ref:`Authentication Error <node-troubleshooting-connection-string-auth>`.

Verify User Is in Authentication Database
-----------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
Perhaps "Verify User Permissions in the Authentication Database" would be more specific. The user can be denied permissions in the auth database, so it wouldn't be limited to checking for existence there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This specific issue is something that was documented on multiple forum posts that the programmer created the user in another database other than the default, such as userPermissions or such. When they moved the user over to that database or specified that database to use as the authentication database, it worked. So I believe this terminology is correct. The user itself needs to exist in the database.

Verifying user permissions is also an issue and can be a different item (although interestingly, that didn't come up in any searching - maybe because it is standard enough that folks know to check it).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revisiting the doc, I don't remember whether which error this specific one was tied to (there are two duplicate headers), but if this one is tied to "com.mongodb.MongoSocketWriteException: Exception sending message", I would guess that this has to do with the network and not with authentication nor authorization. I would double check with DBX engineers or get an external review to verify this potential cause.

Regarding authentication and authorization:

Unless I'm mistaken, if the user does not have any roles, they cannot perform any actions. When the driver attempts to run a command with that user for a command they do not have permissions in their role for, the server will return an error.

When you create a user in the authentication database, you must define their authorization roles to have permissions to do anything. E.g. https://www.mongodb.com/docs/manual/tutorial/create-users/#create-additional-users-for-your-deployment

In a local deployment, you don't need a user and automatically get admin access as that unnamed user.


Verify the user is in the correct authentication database. For more
information about the authentication database, see
:ref:`Authentication Error <node-troubleshooting-connection-admin>`.

Configure Firewall
------------------

The firewall needs to have an open port for communicating with the MongoDB
instance. For more information about configuring the firewall, see
:ref:`Connection Error <node-troubleshooting-connection-firewall>`.

.. _node-troubleshooting-connection-number-connections:

Check the Number of Connections
-------------------------------

This solution could apply to the generic message, as well as the following
specific error message:

.. code-block:: none
:copyable: false

connection refused because too many open connections
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:

Since the rest are split out by error message and potential solutions, I think it would make sense to split this one into its own heading to ensure there's a uniform structure and therefore expectation of where to find information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to avoid duplicating too much and avoiding too many internal links. The issue is that this solution could work either for the generic error message or for this specific error message. It felt like it was too much repetition for very similar types of errors.


Each ``MongoClient`` instance supports a maximum number of concurrent open
connections in its connection pool. The configuration parameter ``maxPoolSize``
defines this value and is set to ``100`` by default. If there are already a
number of open connections equal to ``maxPoolSize``, the server waits until
a connection becomes available. If this wait time exceeds the ``maxIdleTimeMS``
value, the driver responds with an error.

For more information about how connection pooling works, see
:ref:`How Does Connection Pooling Work in the Node Driver? <node-faq-connection-pool>`
in the FAQ.

Timeout Error
~~~~~~~~~~~~~

Sometimes when you send a request through the driver to the server, the request
times out. When this happens, you might receive an error message
similar to the following message:

.. code-block:: none
:copyable: false

timed out while checking out a connection from connection pool: context canceled

If you receive this error, try the following methods to resolve the
issue.

Set connectTimeoutMS
--------------------

To prevent the driver from hanging during connection or to prevent the
driver from spending too long trying to reach unreachable replica sets,
you can set the ``connectTimeoutMS`` option of your
:ref:`connection options <node-connection-options>`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue:

I think it's better to refer to a link by title and location rather than omit it per the style guide's recommendations.

The linked text should correspond to the title of the guide.

Perhaps changing the first sentence to explain the problem and solution before introducing the option.

E.g.

"The driver may hang when it is unable to to establish a connection because it spends too much time attempting to reach unreachable replica set nodes. To prevent the driver from spending too much time attempting to establish the connection, you can set a timeout by using the connectTimeMS setting. To learn more about this setting, see the :ref:`connection options ` guide."

You should ensure the ``connectTimeoutMS`` setting is not lower than
the longest network latency you have to a member of the set. If one of the
secondary members is on the other side of the planet and has a latency of 10000
milliseconds, setting the ``connectTimeoutMS`` to anything lower will
prevent the driver from ever connecting to that member.

The following example sets ``connectTimeoutMS`` to 10000 milliseconds.

.. code-block:: javascript

const client = new MongoClient(uri, {
connectTimeoutMS: 10000,
});

Check the Number of Connections
-------------------------------

The number of connections to the server may exceed ``maxPoolSize``. For more
information about checking the number of connections, see
:ref:`Error Sending Message <node-troubleshooting-connection-number-connections>`.
Loading