diff --git a/server/src/main/java/org/elasticsearch/action/search/ClearScrollController.java b/server/src/main/java/org/elasticsearch/action/search/ClearScrollController.java index 9b98691dc90..c33eecee8bc 100644 --- a/server/src/main/java/org/elasticsearch/action/search/ClearScrollController.java +++ b/server/src/main/java/org/elasticsearch/action/search/ClearScrollController.java @@ -133,10 +133,13 @@ final class ClearScrollController implements Runnable { private void onFailedFreedContext(Throwable e, DiscoveryNode node) { logger.warn(() -> new ParameterizedMessage("Clear SC failed on node[{}]", node), e); + /* + * We have to set the failure marker before we count down otherwise we can expose the failure marker before we have set it to a + * racing thread successfully freeing a context. This would lead to that thread responding that the clear scroll succeeded. + */ + hasFailed.set(true); if (expectedOps.countDown()) { listener.onResponse(new ClearScrollResponse(false, freedSearchContexts.get())); - } else { - hasFailed.set(true); } } }