We saw a case where the recovery stats reported `recovered_bytes` greater than `length_in_bytes` for one file:

```
GET /_recovery?detailed

200 OK
...
{
  "name": "_buk.fdt",
  "length_in_bytes": 26891307173,
  "reused": false,
  "recovered_in_bytes": 35324928266,
  "recovered_from_snapshot_in_bytes": 8433621093
}
...
```

NB `35324928266 == 26891307173 + 8433621093`

This causes Elasticsearch to compute a negative value for the reserved space on the target node of this recovery, which prevents stats APIs from working. This appears to be caused by a network-level failure which triggers a retry without first cancelling an ongoing download of a different file with the same name from the snapshot repository.

---

### Workaround

Restart the target node to clear these stats.
server/src/main/java/org/elasticsearch/index/shard/IndexShard.java
assert safeCommit.get().localCheckpoint <= globalCheckpoint : safeCommit.get().localCheckpoint + " > " + globalCheckpoint;
            if (safeCommit.get().localCheckpoint == globalCheckpoint) {
                logger.trace(
                    "skip local recovery as the safe commit is up to date; safe commit {} global checkpoint {}",
                    safeCommit.get(),
                    globalCheckpoint
                );
                recoveryState.getTranslog().totalLocal(0);
                return globalCheckpoint + 1;
            }
            if (indexSettings.getIndexMetadata().getState() == IndexMetadata.State.CLOSE
                || IndexMetadata.INDEX_BLOCKS_WRITE_SETTING.get(indexSettings.getSettings())) {
                logger.trace(
                    "skip local recovery as the index was closed or not allowed to write; safe commit {} global checkpoint {}",
                    safeCommit.get(),
                    globalCheckpoint
                );
                recoveryState.getTranslog().totalLocal(0);
                return safeCommit.get().localCheckpoint + 1;
            }
            try {
                final Engine.TranslogRecoveryRunner translogRecoveryRunner = (engine, snapshot) -> {
                    recoveryState.getTranslog().totalLocal(snapshot.totalOperations());
                    final int recoveredOps = runTranslogRecovery(
                        engine,
                        snapshot,
                        Engine.Operation.Origin.LOCAL_TRANSLOG_RECOVERY,
                        recoveryState.getTranslog()::incrementRecoveredOperations
                    );
                    recoveryState.getTranslog().totalLocal(recoveredOps);