From 436a831838f7534d3b5bb8ea87039b7524c7c1e4 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 9 Apr 2025 14:20:43 -0600 Subject: [PATCH 1/5] Fix missing index handling for partial-enabled queries --- ...CrossClusterQueryWithPartialResultsIT.java | 40 ++++++++++--------- .../esql/plugin/ClusterComputeHandler.java | 20 +++++++--- .../xpack/esql/plugin/ComputeService.java | 5 ++- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryWithPartialResultsIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryWithPartialResultsIT.java index 463dbb81304a1..810a00c4e06e7 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryWithPartialResultsIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryWithPartialResultsIT.java @@ -135,29 +135,31 @@ public void testPartialResults() throws Exception { } } - public void testOneRemoteClusterPartial() throws Exception { + public void testLocalIndexMissing() throws Exception { populateIndices(); EsqlQueryRequest request = new EsqlQueryRequest(); - request.query("FROM ok*,cluster-a:ok*,*-b:fail* | KEEP id, fail_me"); - request.allowPartialResults(true); + request.query("FROM ok-local,no_such_index | LIMIT 1"); request.includeCCSMetadata(randomBoolean()); - try (var resp = runQuery(request)) { - assertTrue(resp.isPartial()); - Set allIds = Stream.of(local.okIds, remote1.okIds).flatMap(Collection::stream).collect(Collectors.toSet()); - List> rows = getValuesList(resp); - assertThat(rows.size(), equalTo(allIds.size())); - Set returnedIds = new HashSet<>(); - for (List row : rows) { - assertThat(row.size(), equalTo(2)); - String id = (String) row.get(0); - assertTrue(returnedIds.add(id)); - } - assertThat(returnedIds, equalTo(allIds)); + for (boolean allowPartial : Set.of(true, false)) { + request.allowPartialResults(allowPartial); + Exception error = expectThrows(Exception.class, () -> runQuery(request).close()); + error = EsqlTestUtils.unwrapIfWrappedInRemoteException(error); + assertThat(error.getMessage(), containsString("no such index")); + assertThat(error.getMessage(), containsString("[no_such_index]")); + } + } - assertClusterSuccess(resp, LOCAL_CLUSTER, local.okShards); - assertClusterSuccess(resp, REMOTE_CLUSTER_1, remote1.okShards); - assertClusterPartial(resp, REMOTE_CLUSTER_2, remote2.failingShards, 0); - assertClusterFailure(resp, REMOTE_CLUSTER_2, "Accessing failing field"); + public void testRemoteIndexMissing() throws Exception { + populateIndices(); + EsqlQueryRequest request = new EsqlQueryRequest(); + request.query("FROM cluster-a:ok-cluster1,cluster-a:no_such_index | LIMIT 1"); + request.includeCCSMetadata(randomBoolean()); + for (boolean allowPartial : Set.of(true, false)) { + request.allowPartialResults(allowPartial); + Exception error = expectThrows(Exception.class, () -> runQuery(request).close()); + error = EsqlTestUtils.unwrapIfWrappedInRemoteException(error); + assertThat(error.getMessage(), containsString("no such index")); + assertThat(error.getMessage(), containsString("[no_such_index]")); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ClusterComputeHandler.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ClusterComputeHandler.java index 5ad81177a6a44..bf25a781610c0 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ClusterComputeHandler.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ClusterComputeHandler.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.esql.plugin; +import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListenerResponseHandler; import org.elasticsearch.action.OriginalIndices; @@ -16,6 +17,7 @@ import org.elasticsearch.compute.operator.exchange.ExchangeSourceHandler; import org.elasticsearch.core.Releasable; import org.elasticsearch.core.TimeValue; +import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskCancelledException; @@ -88,12 +90,18 @@ void startComputeOnRemoteCluster( if (receivedResults == false && EsqlCCSUtils.shouldIgnoreRuntimeError(executionInfo, clusterAlias, e)) { EsqlCCSUtils.markClusterWithFinalStateAndNoShards(executionInfo, clusterAlias, EsqlExecutionInfo.Cluster.Status.SKIPPED, e); l.onResponse(List.of()); - } else if (configuration.allowPartialResults()) { - EsqlCCSUtils.markClusterWithFinalStateAndNoShards(executionInfo, clusterAlias, EsqlExecutionInfo.Cluster.Status.PARTIAL, e); - l.onResponse(List.of()); - } else { - l.onFailure(e); - } + } else if (configuration.allowPartialResults() + && (ExceptionsHelper.unwrapCause(e) instanceof IndexNotFoundException) == false) { + EsqlCCSUtils.markClusterWithFinalStateAndNoShards( + executionInfo, + clusterAlias, + EsqlExecutionInfo.Cluster.Status.PARTIAL, + e + ); + l.onResponse(List.of()); + } else { + l.onFailure(e); + } }); ExchangeService.openExchange( transportService, diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java index 5724587f0573b..3ccb22fdfee78 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.esql.plugin; +import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.OriginalIndices; import org.elasticsearch.action.search.SearchRequest; @@ -27,6 +28,7 @@ import org.elasticsearch.core.Releasables; import org.elasticsearch.core.TimeValue; import org.elasticsearch.core.Tuple; +import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.logging.LogManager; import org.elasticsearch.logging.Logger; @@ -314,7 +316,8 @@ public void execute( ); dataNodesListener.onResponse(r.getProfiles()); }, e -> { - if (configuration.allowPartialResults()) { + if (configuration.allowPartialResults() + && (ExceptionsHelper.unwrapCause(e) instanceof IndexNotFoundException) == false) { execInfo.swapCluster( LOCAL_CLUSTER, (k, v) -> new EsqlExecutionInfo.Cluster.Builder(v).setStatus( From 39141cc7cca72501a2f652930780750ed294e71c Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 9 Apr 2025 14:31:24 -0600 Subject: [PATCH 2/5] Oops shouldn't delete that --- ...CrossClusterQueryWithPartialResultsIT.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryWithPartialResultsIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryWithPartialResultsIT.java index 810a00c4e06e7..c6d45486549e2 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryWithPartialResultsIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryWithPartialResultsIT.java @@ -135,6 +135,32 @@ public void testPartialResults() throws Exception { } } + public void testOneRemoteClusterPartial() throws Exception { + populateIndices(); + EsqlQueryRequest request = new EsqlQueryRequest(); + request.query("FROM ok*,cluster-a:ok*,*-b:fail* | KEEP id, fail_me"); + request.allowPartialResults(true); + request.includeCCSMetadata(randomBoolean()); + try (var resp = runQuery(request)) { + assertTrue(resp.isPartial()); + Set allIds = Stream.of(local.okIds, remote1.okIds).flatMap(Collection::stream).collect(Collectors.toSet()); + List> rows = getValuesList(resp); + assertThat(rows.size(), equalTo(allIds.size())); + Set returnedIds = new HashSet<>(); + for (List row : rows) { + assertThat(row.size(), equalTo(2)); + String id = (String) row.get(0); + assertTrue(returnedIds.add(id)); + } + assertThat(returnedIds, equalTo(allIds)); + + assertClusterSuccess(resp, LOCAL_CLUSTER, local.okShards); + assertClusterSuccess(resp, REMOTE_CLUSTER_1, remote1.okShards); + assertClusterPartial(resp, REMOTE_CLUSTER_2, remote2.failingShards, 0); + assertClusterFailure(resp, REMOTE_CLUSTER_2, "Accessing failing field"); + } + } + public void testLocalIndexMissing() throws Exception { populateIndices(); EsqlQueryRequest request = new EsqlQueryRequest(); From d3421a1b1c51be55e3510bad506f05799c629512 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Fri, 11 Apr 2025 13:28:52 -0600 Subject: [PATCH 3/5] Set ignore_unavaliable to false --- .../org/elasticsearch/xpack/esql/session/IndexResolver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/IndexResolver.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/IndexResolver.java index d2f79ceb1316f..a378949edea2a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/IndexResolver.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/IndexResolver.java @@ -56,7 +56,7 @@ public class IndexResolver { public static final String UNMAPPED = "unmapped"; public static final IndicesOptions FIELD_CAPS_INDICES_OPTIONS = IndicesOptions.builder() - .concreteTargetOptions(IndicesOptions.ConcreteTargetOptions.ALLOW_UNAVAILABLE_TARGETS) + .concreteTargetOptions(IndicesOptions.ConcreteTargetOptions.ERROR_WHEN_UNAVAILABLE_TARGETS) .wildcardOptions( IndicesOptions.WildcardOptions.builder() .matchOpen(true) From a4d00121a4493d14e4cf8a434155355e813d7872 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Fri, 11 Apr 2025 18:16:08 -0600 Subject: [PATCH 4/5] test fixes --- .../esql/action/CrossClusterQueryIT.java | 67 +++++++++++++------ .../esql/plugin/ClusterComputeHandler.java | 20 ++---- .../xpack/esql/plugin/ComputeService.java | 5 +- 3 files changed, 53 insertions(+), 39 deletions(-) diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryIT.java index fe5c36aff07e7..25ee30e6161c6 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueryIT.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.esql.action; import org.elasticsearch.Build; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse; @@ -156,14 +157,10 @@ public void testSearchesAgainstNonMatchingIndicesWithLocalOnly() throws Exceptio { String q = "FROM nomatch," + localIndex; - IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> runQuery(q, false)); - assertThat(e.getDetailedMessage(), containsString("no such index [nomatch]")); + expectNotFoundExceptionForQuery(q, "no such index [nomatch]", false); - // MP TODO: am I able to fix this from the field-caps call? Yes, if we detect concrete vs. wildcard expressions in user query - // TODO bug - this does not throw; uncomment this test once https://github.com/elastic/elasticsearch/issues/114495 is fixed - // String limit0 = q + " | LIMIT 0"; - // VerificationException ve = expectThrows(VerificationException.class, () -> runQuery(limit0, false)); - // assertThat(ve.getDetailedMessage(), containsString("No matching indices for [nomatch]")); + String limit0 = q + " | LIMIT 0"; + expectNotFoundExceptionForQuery(limit0, "no such index [nomatch]", false); } { @@ -187,8 +184,8 @@ public void testSearchesAgainstNonMatchingIndicesWithLocalOnly() throws Exceptio } { String q = "FROM nomatch"; - String expectedError = "Unknown index [nomatch]"; - expectVerificationExceptionForQuery(q, expectedError, false); + String expectedError = "no such index [nomatch]"; + expectNotFoundExceptionForQuery(q, expectedError, false); } { String q = "FROM nomatch*"; @@ -273,8 +270,8 @@ public void testSearchesAgainstNonMatchingIndices() throws Exception { // missing concrete local index is an error { String q = "FROM nomatch,cluster-a:" + remote1Index; - String expectedError = "Unknown index [nomatch]"; - expectVerificationExceptionForQuery(q, expectedError, requestIncludeMeta); + String expectedError = "no such index [nomatch]"; + expectNotFoundExceptionForQuery(q, expectedError, requestIncludeMeta); } // missing concrete remote index is fatal @@ -284,6 +281,13 @@ public void testSearchesAgainstNonMatchingIndices() throws Exception { expectVerificationExceptionForQuery(q, expectedError, requestIncludeMeta); } + // missing concrete remote index is fatal + { + String q = "FROM logs*,cluster-a:logs*,cluster-a:nomatch"; + String expectedError = "Unknown index [cluster-a:logs*,nomatch]"; + expectVerificationExceptionForQuery(q, expectedError, requestIncludeMeta); + } + // No error since local non-matching index has wildcard and the remote cluster index expression matches { String remote1IndexName = randomFrom(remote1Index, IDX_ALIAS, FILTERED_IDX_ALIAS); @@ -368,8 +372,8 @@ public void testSearchesAgainstNonMatchingIndices() throws Exception { // an error is thrown if there is a concrete index that does not match { String q = "FROM cluster-a:nomatch"; - String expectedError = "Unknown index [cluster-a:nomatch]"; - expectVerificationExceptionForQuery(q, expectedError, requestIncludeMeta); + String expectedError = "no such index [nomatch]"; + expectExceptionForQuery(q, expectedError, requestIncludeMeta, IndexNotFoundException.class); } // an error is thrown if there are no matching indices at all - single remote cluster with wildcard index expression @@ -382,8 +386,8 @@ public void testSearchesAgainstNonMatchingIndices() throws Exception { // an error is thrown if there is a concrete index that does not match { String q = "FROM nomatch*,cluster-a:nomatch"; - String expectedError = "Unknown index [cluster-a:nomatch,nomatch*]"; - expectVerificationExceptionForQuery(q, expectedError, requestIncludeMeta); + String expectedError = "no such index [nomatch]"; + expectNotFoundExceptionForQuery(q, expectedError, requestIncludeMeta); } // an error is thrown if there are no matching indices at all - local with wildcard, remote with wildcard @@ -394,13 +398,13 @@ public void testSearchesAgainstNonMatchingIndices() throws Exception { } { String q = "FROM nomatch,cluster-a:nomatch"; - String expectedError = "Unknown index [cluster-a:nomatch,nomatch]"; - expectVerificationExceptionForQuery(q, expectedError, requestIncludeMeta); + String expectedError = "no such index [nomatch]"; + expectNotFoundExceptionForQuery(q, expectedError, requestIncludeMeta); } { String q = "FROM nomatch,cluster-a:nomatch*"; - String expectedError = "Unknown index [cluster-a:nomatch*,nomatch]"; - expectVerificationExceptionForQuery(q, expectedError, requestIncludeMeta); + String expectedError = "no such index [nomatch]"; + expectNotFoundExceptionForQuery(q, expectedError, requestIncludeMeta); } // --- test against 3 clusters @@ -422,11 +426,32 @@ record ExpectedCluster(String clusterAlias, String indexExpression, EsqlExecutio * extra processing step to ensure that ESQL coordinator-only operations throw the same VerificationError. */ private void expectVerificationExceptionForQuery(String query, String error, Boolean requestIncludeMeta) { - VerificationException e = expectThrows(VerificationException.class, () -> runQuery(query, requestIncludeMeta)); + expectExceptionForQuery(query, error, requestIncludeMeta, VerificationException.class); + } + + /** + * Runs the provided query, expecting a VerificationError. It then runs the same query with a "| LIMIT 0" + * extra processing step to ensure that ESQL coordinator-only operations throw the same VerificationError. + */ + private void expectNotFoundExceptionForQuery(String query, String error, Boolean requestIncludeMeta) { + expectExceptionForQuery(query, error, requestIncludeMeta, IndexNotFoundException.class); + } + + /** + * Runs the provided query, expecting a VerificationError. It then runs the same query with a "| LIMIT 0" + * extra processing step to ensure that ESQL coordinator-only operations throw the same VerificationError. + */ + private void expectExceptionForQuery( + String query, + String error, + Boolean requestIncludeMeta, + Class clazz + ) { + ET e = expectThrows(clazz, () -> runQuery(query, requestIncludeMeta)); assertThat(e.getDetailedMessage(), containsString(error)); String limit0 = query + " | LIMIT 0"; - e = expectThrows(VerificationException.class, () -> runQuery(limit0, requestIncludeMeta)); + e = expectThrows(clazz, () -> runQuery(limit0, requestIncludeMeta)); assertThat(e.getDetailedMessage(), containsString(error)); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ClusterComputeHandler.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ClusterComputeHandler.java index bf25a781610c0..5ad81177a6a44 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ClusterComputeHandler.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ClusterComputeHandler.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.esql.plugin; -import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListenerResponseHandler; import org.elasticsearch.action.OriginalIndices; @@ -17,7 +16,6 @@ import org.elasticsearch.compute.operator.exchange.ExchangeSourceHandler; import org.elasticsearch.core.Releasable; import org.elasticsearch.core.TimeValue; -import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskCancelledException; @@ -90,18 +88,12 @@ void startComputeOnRemoteCluster( if (receivedResults == false && EsqlCCSUtils.shouldIgnoreRuntimeError(executionInfo, clusterAlias, e)) { EsqlCCSUtils.markClusterWithFinalStateAndNoShards(executionInfo, clusterAlias, EsqlExecutionInfo.Cluster.Status.SKIPPED, e); l.onResponse(List.of()); - } else if (configuration.allowPartialResults() - && (ExceptionsHelper.unwrapCause(e) instanceof IndexNotFoundException) == false) { - EsqlCCSUtils.markClusterWithFinalStateAndNoShards( - executionInfo, - clusterAlias, - EsqlExecutionInfo.Cluster.Status.PARTIAL, - e - ); - l.onResponse(List.of()); - } else { - l.onFailure(e); - } + } else if (configuration.allowPartialResults()) { + EsqlCCSUtils.markClusterWithFinalStateAndNoShards(executionInfo, clusterAlias, EsqlExecutionInfo.Cluster.Status.PARTIAL, e); + l.onResponse(List.of()); + } else { + l.onFailure(e); + } }); ExchangeService.openExchange( transportService, diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java index 86de782e61b42..6ebaeca1e56c0 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.esql.plugin; -import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.OriginalIndices; import org.elasticsearch.action.search.SearchRequest; @@ -29,7 +28,6 @@ import org.elasticsearch.core.Releasables; import org.elasticsearch.core.TimeValue; import org.elasticsearch.core.Tuple; -import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.logging.LogManager; import org.elasticsearch.logging.Logger; @@ -320,8 +318,7 @@ public void execute( ); dataNodesListener.onResponse(r.getProfiles()); }, e -> { - if (configuration.allowPartialResults() - && (ExceptionsHelper.unwrapCause(e) instanceof IndexNotFoundException) == false) { + if (configuration.allowPartialResults()) { execInfo.swapCluster( LOCAL_CLUSTER, (k, v) -> new EsqlExecutionInfo.Cluster.Builder(v).setStatus( From bbf64a65c07689e58aeb24142f9585ae1f1ff39c Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 16 Apr 2025 10:23:41 -0600 Subject: [PATCH 5/5] test fix --- .../xpack/esql/qa/rest/RequestIndexFilteringTestCase.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java index 1fdc11174ee09..309038107f570 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java @@ -199,9 +199,9 @@ public void testIndicesDontExist() throws IOException { indexTimestampData(docsTest1, "test1", "2024-11-26", "id1"); ResponseException e = expectThrows(ResponseException.class, () -> runEsql(timestampFilter("gte", "2020-01-01").query(from("foo")))); - assertEquals(400, e.getResponse().getStatusLine().getStatusCode()); - assertThat(e.getMessage(), containsString("verification_exception")); - assertThat(e.getMessage(), anyOf(containsString("Unknown index [foo]"), containsString("Unknown index [remote_cluster:foo]"))); + assertEquals(404, e.getResponse().getStatusLine().getStatusCode()); + assertThat(e.getMessage(), containsString("index_not_found_exception")); + assertThat(e.getMessage(), anyOf(containsString("no such index [foo]"), containsString("Unknown index [remote_cluster:foo]"))); e = expectThrows(ResponseException.class, () -> runEsql(timestampFilter("gte", "2020-01-01").query(from("foo*")))); assertEquals(400, e.getResponse().getStatusLine().getStatusCode());