### CI Link

https://gradle-enterprise.elastic.co/s/ptwgurvvtzx5s

### Repro line

Probably with `./gradlew :qa:full-cluster-restart:v7.0.1#upgradedClusterTest`

### Does it reproduce?

Didn't try

### Applicable branches

main

### Failure history

_No response_

### Failure excerpt

See https://gradle-enterprise.elastic.co/s/ptwgurvvtzx5s/console-log/raw?task=:qa:full-cluster-restart:v7.0.1%23upgradedClusterTest

It also fails for other BWC versions: https://elasticsearch-ci.elastic.co/job/elastic+elasticsearch+main+periodic+bwc/
(7.0.0 to 7.1.1)

```
» [2022-11-09T13:11:28,587][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [v7.0.1-1] fatal error in thread [elasticsearch[v7.0.1-1][masterService#updateTask][T#1]], exiting java.lang.AssertionError: {[testclosedindices][0]=2}
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceReconciler.allocateUnassignedInvariant(DesiredBalanceReconciler.java:118)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceReconciler.run(DesiredBalanceReconciler.java:81)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceShardsAllocator.recordTime(DesiredBalanceShardsAllocator.java:299)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceShardsAllocator.reconcile(DesiredBalanceShardsAllocator.java:213)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceShardsAllocator$ReconcileDesiredBalanceExecutor.lambda$applyBalance$1(DesiredBalanceShardsAllocator.java:277)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.AllocationService.reroute(AllocationService.java:518)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.AllocationService.executeWithRoutingAllocation(AllocationService.java:444)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.ClusterModule.reconcile(ClusterModule.java:145)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceShardsAllocator$ReconcileDesiredBalanceExecutor.applyBalance(DesiredBalanceShardsAllocator.java:275)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceShardsAllocator$ReconcileDesiredBalanceExecutor.execute(DesiredBalanceShardsAllocator.java:261)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.service.MasterService.innerExecuteTasks(MasterService.java:1052)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.service.MasterService.executeTasks(MasterService.java:1017)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.service.MasterService.runTasks(MasterService.java:278)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.service.MasterService$Batcher.run(MasterService.java:170)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.service.TaskBatcher.runIfNotProcessed(TaskBatcher.java:110)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.cluster.service.TaskBatcher$BatchedTask.run(TaskBatcher.java:148)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:850)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.runAndClean(PrioritizedEsThreadPoolExecutor.java:257)
»  	at org.elasticsearch.server@8.6.0-SNAPSHOT/org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedEsThreadPoolExecutor.java:223)
»  	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
»  	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
»  	at java.base/java.lang.Thread.run(Thread.java:833)
```
server/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceReconciler.java
secondaryLength = 0;
        } while (primaryLength > 0);
    }
    private Iterable<String> getDesiredNodesIds(ShardRouting shard, ShardAssignment assignment) {
        return allocationOrdering.sort(allocation.deciders().getForcedInitialShardAllocationToNodes(shard, allocation).map(forced -> {
            if (logger.isDebugEnabled()) {
                logger.debug("Shard [{}] assignment is ignored. Initial allocation forced to {}", shard.shardId(), forced);
            }
            return forced;
        }).orElse(assignment.nodeIds()));
    }
    private Iterable<String> getFallbackNodeIds(ShardRouting shard, AtomicBoolean isThrottled) {
        return () -> {
            if (shard.primary() && isThrottled.get() == false) {
                var fallbackNodeIds = allocation.routingNodes().stream().map(RoutingNode::nodeId).toList();
                if (logger.isDebugEnabled()) {
                    logger.trace("Shard [{}] assignment is temporary not possible. Falling back to {}", shard.shardId(), fallbackNodeIds);
                }
                return allocationOrdering.sort(fallbackNodeIds).iterator();
            } else {
                return Collections.emptyIterator();
            }
        };
    }
    private void moveShards() {
        
        
        
        for (final var iterator = routingNodes.nodeInterleavedShardIterator(); iterator.hasNext();) {
            final var shardRouting = iterator.next();