diff --git a/elasticsearch/client/cluster.py b/elasticsearch/client/cluster.py
index 0b3dee93..14fa7e94 100644
--- a/elasticsearch/client/cluster.py
+++ b/elasticsearch/client/cluster.py
@@ -102,6 +102,9 @@ class ClusterClient(NamespacedClient):
         :arg wait_for_timeout: The maximum time to wait for
             wait_for_metadata_version before timing out
         """
+        if index and metric in SKIP_IN_PATH:
+            metric = "_all"
+
         return self.transport.perform_request(
             "GET", _make_path("_cluster", "state", metric, index), params=params
         )
diff --git a/utils/templates/overrides/cluster/state b/utils/templates/overrides/cluster/state
new file mode 100644
index 00000000..27d599cb
--- /dev/null
+++ b/utils/templates/overrides/cluster/state
@@ -0,0 +1,8 @@
+{% extends "base" %}
+{% block request %}
+        if index and metric in SKIP_IN_PATH:
+            metric = "_all"
+
+        {{ super()|trim }}
+{% endblock %}
+

cluster.state(index='name')['routing_table'] not found in client 7.5.1
Using the most recent release of the Elasticsearch Python client (7.5.1 at this time), the cluster state endpoint is not defaulting to show `_all` keys.

### 7.5.1

```
client.cluster.state(index=idx).keys()
dict_keys(['cluster_name', 'cluster_uuid'])
```

### 7.1.1:

```
client.cluster.state(index=idx).keys()
dict_keys(['cluster_name', 'cluster_uuid', 'version', 'state_uuid', 'master_node', 'blocks', 'nodes', 'metadata', 'routing_table', 'routing_nodes'])
```

This omission, if intended, would seem to be something to change in a major release version, rather than a minor release.

This was detected and reported [here](https://github.com/elastic/support-dev-help/issues/10455#issue-558049925). This compels me to pin Curator at client version `elasticsearch==7.1.0` for now.
diff --git a/test_elasticsearch/test_client/test_cluster.py b/test_elasticsearch/test_client/test_cluster.py
new file mode 100644
index 00000000..a0b9d741
--- /dev/null
+++ b/test_elasticsearch/test_client/test_cluster.py
@@ -0,0 +1,27 @@
+from test_elasticsearch.test_cases import ElasticsearchTestCase
+
+
+class TestCluster(ElasticsearchTestCase):
+    def test_stats_without_node_id(self):
+        self.client.cluster.stats()
+        self.assert_url_called("GET", "/_cluster/stats")
+
+    def test_stats_with_node_id(self):
+        self.client.cluster.stats("node-1")
+        self.assert_url_called("GET", "/_cluster/stats/nodes/node-1")
+
+        self.client.cluster.stats(node_id="node-2")
+        self.assert_url_called("GET", "/_cluster/stats/nodes/node-2")
+
+    def test_state_with_index_without_metric_defaults_to_all(self):
+        self.client.cluster.state()
+        self.assert_url_called("GET", "/_cluster/state")
+
+        self.client.cluster.state(metric="cluster_name")
+        self.assert_url_called("GET", "/_cluster/state/cluster_name")
+
+        self.client.cluster.state(index="index-1")
+        self.assert_url_called("GET", "/_cluster/state/_all/index-1")
+
+        self.client.cluster.state(index="index-1", metric="cluster_name")
+        self.assert_url_called("GET", "/_cluster/state/cluster_name/index-1")
diff --git a/test_elasticsearch/test_client/test_indices.py b/test_elasticsearch/test_client/test_indices.py
index 7d80562a..7fdfc734 100644
--- a/test_elasticsearch/test_client/test_indices.py
+++ b/test_elasticsearch/test_client/test_indices.py
@@ -18,3 +18,7 @@ class TestIndices(ElasticsearchTestCase):
         self.assertRaises(ValueError, self.client.indices.exists, index=None)
         self.assertRaises(ValueError, self.client.indices.exists, index=[])
         self.assertRaises(ValueError, self.client.indices.exists, index="")
+
+    def test_put_mapping_without_index(self):
+        self.client.indices.put_mapping(doc_type="doc-type", body={})
+        self.assert_url_called("PUT", "/_all/doc-type/_mapping")
diff --git a/test_elasticsearch/test_server/__init__.py b/test_elasticsearch/test_server/__init__.py
index 9c116675..159750a6 100644
--- a/test_elasticsearch/test_server/__init__.py
+++ b/test_elasticsearch/test_server/__init__.py
@@ -1,3 +1,4 @@
+from unittest import SkipTest
 from elasticsearch.helpers import test
 from elasticsearch.helpers.test import ElasticsearchTestCase as BaseTestCase
 
@@ -6,6 +7,8 @@ client = None
 
 def get_client(**kwargs):
     global client
+    if client is False:
+        raise SkipTest("No client is available")
     if client is not None and not kwargs:
         return client
 
@@ -16,7 +19,11 @@ def get_client(**kwargs):
         new_client = local_get_client(**kwargs)
     except ImportError:
         # fallback to using vanilla client
-        new_client = test.get_test_client(**kwargs)
+        try:
+            new_client = test.get_test_client(**kwargs)
+        except SkipTest:
+            client = False
+            raise
 
     if not kwargs:
         client = new_client

pip install -e .[develop]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio
apt-get update apt-get install -y gcc
3.7
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
Babel==2.14.0
black==23.3.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
charset-normalizer==3.4.1
click==8.1.8
coverage==7.2.7
docutils==0.18.1
-e git+https://github.com/elastic/elasticsearch-py.git@5611445203ebabb1a450b17c2c93cd3546a12071#egg=elasticsearch
exceptiongroup==1.2.2
execnet==2.0.2
idna==3.10
imagesize==1.4.1
importlib-metadata==6.7.0
iniconfig==2.0.0
Jinja2==3.1.6
MarkupSafe==2.1.5
mock==5.2.0
mypy-extensions==1.0.0
nose==1.3.7
nosexcover==1.0.11
packaging==24.0
pathspec==0.11.2
platformdirs==4.0.0
pluggy==1.2.0
Pygments==2.17.2
pytest==7.4.4
pytest-asyncio==0.21.2
pytest-cov==4.1.0
pytest-mock==3.11.1
pytest-xdist==3.5.0
pytz==2025.2
PyYAML==6.0.1
requests==2.31.0
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==2.0.1
typed-ast==1.5.5
typing_extensions==4.7.1
urllib3==2.0.7
zipp==3.15.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=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - 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=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - babel==2.14.0
      - black==23.3.0
      - charset-normalizer==3.4.1
      - click==8.1.8
      - coverage==7.2.7
      - docutils==0.18.1
      - exceptiongroup==1.2.2
      - execnet==2.0.2
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - jinja2==3.1.6
      - markupsafe==2.1.5
      - mock==5.2.0
      - mypy-extensions==1.0.0
      - nose==1.3.7
      - nosexcover==1.0.11
      - packaging==24.0
      - pathspec==0.11.2
      - platformdirs==4.0.0
      - pluggy==1.2.0
      - pygments==2.17.2
      - pytest==7.4.4
      - pytest-asyncio==0.21.2
      - pytest-cov==4.1.0
      - pytest-mock==3.11.1
      - pytest-xdist==3.5.0
      - pytz==2025.2
      - pyyaml==6.0.1
      - requests==2.31.0
      - 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==2.0.1
      - typed-ast==1.5.5
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - zipp==3.15.0
prefix: /opt/conda/envs/elasticsearch-py

test_elasticsearch/test_client/test_cluster.py::TestCluster::test_state_with_index_without_metric_defaults_to_all
test_elasticsearch/test_client/test_cluster.py::TestCluster::test_stats_with_node_id test_elasticsearch/test_client/test_cluster.py::TestCluster::test_stats_without_node_id test_elasticsearch/test_client/test_indices.py::TestIndices::test_create_one_index test_elasticsearch/test_client/test_indices.py::TestIndices::test_delete_multiple_indices test_elasticsearch/test_client/test_indices.py::TestIndices::test_exists_index test_elasticsearch/test_client/test_indices.py::TestIndices::test_passing_empty_value_for_required_param_raises_exception test_elasticsearch/test_client/test_indices.py::TestIndices::test_put_mapping_without_index
elasticsearch/client/cluster.py utils/templates/overrides/cluster/state
elasticsearch/client/cluster.py utils/templates/overrides/cluster/state