### 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
for (final var shardRouting : routingNode) {
                shardCounts.computeIfPresent(shardRouting.shardId(), (ignored, count) -> count == 1 ? null : count - 1);
            }
        }
        assert shardCounts.isEmpty() : shardCounts;
        return true;
    }
    private void failAllocationOfNewPrimaries(RoutingAllocation allocation) {
        RoutingNodes routingNodes = allocation.routingNodes();
        assert routingNodes.size() == 0 : routingNodes;
        final RoutingNodes.UnassignedShards.UnassignedIterator unassignedIterator = routingNodes.unassigned().iterator();
        while (unassignedIterator.hasNext()) {
            final ShardRouting shardRouting = unassignedIterator.next();
            final UnassignedInfo unassignedInfo = shardRouting.unassignedInfo();
            if (shardRouting.primary() && unassignedInfo.getLastAllocationStatus() == UnassignedInfo.AllocationStatus.NO_ATTEMPT) {
                unassignedIterator.updateUnassigned(
                    new UnassignedInfo(
                        unassignedInfo.getReason(),
                        unassignedInfo.getMessage(),
                        unassignedInfo.getFailure(),
                        unassignedInfo.getNumFailedAllocations(),
                        unassignedInfo.getUnassignedTimeInNanos(),
                        unassignedInfo.getUnassignedTimeInMillis(),
                        unassignedInfo.isDelayed(),
                        UnassignedInfo.AllocationStatus.DECIDERS_NO,
                        unassignedInfo.getFailedNodeIds(),
                        unassignedInfo.getLastAllocatedNodeId()
                    ),
                    shardRouting.recoverySource(),
                    allocation.changes()