HonzaKral: This is great, Could I just ask you to sign the [CLA](https://www.elastic.co/contributor-agreement/) so that we can merge it?

Thank you!
alexk307: Just signed! Thanks
diff --git a/elasticsearch/connection/base.py b/elasticsearch/connection/base.py
index 8bb93a4b..a3fbd780 100644
--- a/elasticsearch/connection/base.py
+++ b/elasticsearch/connection/base.py
@@ -65,7 +65,7 @@ class Connection(object):
             raise TypeError(
                 "Unsupported equality check for %s and %s" % (self, other)
             )
-        return True
+        return self.__hash__() == other.__hash__()
 
     def __hash__(self):
         return id(self)
diff --git a/elasticsearch/connection_pool.py b/elasticsearch/connection_pool.py
index 05277632..d9bdcd29 100644
--- a/elasticsearch/connection_pool.py
+++ b/elasticsearch/connection_pool.py
@@ -150,6 +150,7 @@ class ConnectionPool(object):
         try:
             self.connections.remove(connection)
         except ValueError:
+            logger.info("Attempted to remove %r, but it does not exist in the connection pool.", connection)
             # connection not alive or another thread marked it already, ignore
             return
         else:

mark_dead() in ConnectionPool always removes the first connection in the pool
`ConnectionPool`'s `mark_dead()` method is supposed to remove the dead `connection` from the `connections` list:

`self.connections.remove(connection)`

However the equality comparison implementation `__eq__` in the `Connection` class is incorrect. It always returns `True` as long as both objects are `Connection` instances:

```
def __eq__(self, other):
        if not isinstance(other, Connection):
            raise TypeError(
                "Unsupported equality check for %s and %s" % (self, other)
            )
        return True
```

This defect manifests itself by removing all good connections until the connections is empty. One dead connection will bring down the whole connection pool.

Proposed solution: removing `__eq__` from `Connection`. Thoughts?
diff --git a/test_elasticsearch/test_connection_pool.py b/test_elasticsearch/test_connection_pool.py
index 923497f1..f5a5f2d8 100644
--- a/test_elasticsearch/test_connection_pool.py
+++ b/test_elasticsearch/test_connection_pool.py
@@ -5,6 +5,7 @@ from elasticsearch.connection_pool import (
     RoundRobinSelector,
     DummyConnectionPool,
 )
+from elasticsearch.connection import Connection
 from elasticsearch.exceptions import ImproperlyConfigured
 
 from .test_cases import TestCase
@@ -72,6 +73,17 @@ class TestConnectionPool(TestCase):
             [pool.get_connection(), pool.get_connection(), pool.get_connection()],
         )
 
+    def test_new_connection_is_not_marked_dead(self):
+        # Create 10 connections
+        pool = ConnectionPool([(Connection(), {}) for _ in range(10)])
+
+        # Pass in a new connection that is not in the pool to mark as dead
+        new_connection = Connection()
+        pool.mark_dead(new_connection)
+
+        # Nothing should be marked dead
+        self.assertEquals(0, len(pool.dead_count))
+
     def test_connection_is_forcibly_resurrected_when_no_live_ones_are_availible(self):
         pool = ConnectionPool([(x, {}) for x in range(2)])
         pool.dead_count[0] = 1

pip install -e .[develop]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio pytest
apt-get update apt-get install -y gcc git curl
3.6
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
attrs==22.2.0
Babel==2.11.0
certifi==2021.5.30
charset-normalizer==2.0.12
coverage==6.2
docutils==0.18.1
-e git+https://github.com/elastic/elasticsearch-py.git@fc78c992ef6ceca157f369186760c8c550fb3bc4#egg=elasticsearch
execnet==1.9.0
idna==3.10
imagesize==1.4.1
importlib-metadata==4.8.3
iniconfig==1.1.1
Jinja2==3.0.3
MarkupSafe==2.0.1
mock==5.2.0
nose==1.3.7
nosexcover==1.0.11
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyaml==23.5.8
Pygments==2.14.0
pyparsing==3.1.4
pytest==7.0.1
pytest-asyncio==0.16.0
pytest-cov==4.0.0
pytest-mock==3.6.1
pytest-xdist==3.0.2
pytz==2025.2
PyYAML==6.0.1
requests==2.27.1
six==1.17.0
snowballstemmer==2.2.0
Sphinx==1.6.7
sphinx-rtd-theme==1.2.1
sphinxcontrib-jquery==2.0.0
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-websupport==1.2.4
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.26.20
zipp==3.6.0

name: elasticsearch-py
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - attrs==22.2.0
      - babel==2.11.0
      - charset-normalizer==2.0.12
      - coverage==6.2
      - docutils==0.18.1
      - execnet==1.9.0
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - jinja2==3.0.3
      - markupsafe==2.0.1
      - mock==5.2.0
      - nose==1.3.7
      - nosexcover==1.0.11
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyaml==23.5.8
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-asyncio==0.16.0
      - pytest-cov==4.0.0
      - pytest-mock==3.6.1
      - pytest-xdist==3.0.2
      - pytz==2025.2
      - pyyaml==6.0.1
      - requests==2.27.1
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==1.6.7
      - sphinx-rtd-theme==1.2.1
      - sphinxcontrib-jquery==2.0.0
      - sphinxcontrib-serializinghtml==1.1.5
      - sphinxcontrib-websupport==1.2.4
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - zipp==3.6.0
prefix: /opt/conda/envs/elasticsearch-py

test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_new_connection_is_not_marked_dead
test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_already_failed_connection_has_longer_timeout test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_connection_is_forcibly_resurrected_when_no_live_ones_are_availible test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_connection_is_resurrected_after_its_timeout test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_connection_is_skipped_when_dead test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_dead_count_is_wiped_clean_for_connection_if_marked_live test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_dead_nodes_are_removed_from_active_connections test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_default_round_robin test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_disable_shuffling test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_dummy_cp_raises_exception_on_more_connections test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_force_resurrect_always_returns_a_connection test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_raises_exception_when_no_connections_defined test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_selectors_have_access_to_connection_opts test_elasticsearch/test_connection_pool.py::TestConnectionPool::test_timeout_for_failed_connections_is_limitted
elasticsearch/connection/base.py elasticsearch/connection_pool.py
elasticsearch/connection/base.py elasticsearch/connection_pool.py