diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/ShardFollowTasksExecutor.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/ShardFollowTasksExecutor.java index c0e2d7f54b318..d9af0d6e71c04 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/ShardFollowTasksExecutor.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/ShardFollowTasksExecutor.java @@ -8,6 +8,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.message.ParameterizedMessage; +import org.apache.lucene.store.AlreadyClosedException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; @@ -302,9 +303,21 @@ private void fetchFollowerShardInfo( if (filteredShardStats.isPresent()) { final ShardStats shardStats = filteredShardStats.get(); final CommitStats commitStats = shardStats.getCommitStats(); - final String historyUUID = commitStats.getUserData().get(Engine.HISTORY_UUID_KEY); - + if (commitStats == null) { + // If commitStats is null then AlreadyClosedException has been thrown: TransportIndicesStatsAction#shardOperation(...) + // AlreadyClosedException will be retried byShardFollowNodeTask.shouldRetry(...) + errorHandler.accept(new AlreadyClosedException(shardId + " commit_stats are missing")); + return; + } final SeqNoStats seqNoStats = shardStats.getSeqNoStats(); + if (seqNoStats == null) { + // If seqNoStats is null then AlreadyClosedException has been thrown at TransportIndicesStatsAction#shardOperation(...) + // AlreadyClosedException will be retried byShardFollowNodeTask.shouldRetry(...) + errorHandler.accept(new AlreadyClosedException(shardId + " seq_no_stats are missing")); + return; + } + + final String historyUUID = commitStats.getUserData().get(Engine.HISTORY_UUID_KEY); final long globalCheckpoint = seqNoStats.getGlobalCheckpoint(); final long maxSeqNo = seqNoStats.getMaxSeqNo(); handler.accept(historyUUID, globalCheckpoint, maxSeqNo); diff --git a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/FollowStatsIT.java b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/FollowStatsIT.java index e6662f3770d24..1f1c6cd5c64e3 100644 --- a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/FollowStatsIT.java +++ b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/FollowStatsIT.java @@ -149,7 +149,6 @@ public void testFollowStatsApiResourceNotFound() throws Exception { assertAcked(client().execute(PauseFollowAction.INSTANCE, new PauseFollowAction.Request("follower1")).actionGet()); } - @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/38779") public void testFollowStatsApiIncludeShardFollowStatsWithRemovedFollowerIndex() throws Exception { final String leaderIndexSettings = getIndexSettings(1, 0, singletonMap(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), "true"));