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
* Update the local knowledge of the persisted global checkpoint for the specified allocation ID.
     *
     * @param allocationId     the allocation ID to update the global checkpoint for
     * @param globalCheckpoint the global checkpoint
     */
    public void updateGlobalCheckpointForShard(final String allocationId, final long globalCheckpoint) {
        assert assertPrimaryMode();
        verifyNotClosed();
        replicationTracker.updateGlobalCheckpointForShard(allocationId, globalCheckpoint);
    }
    /**
     * Add a global checkpoint listener. If the global checkpoint is equal to or above the global checkpoint the listener is waiting for,
     * then the listener will be notified immediately via an executor (so possibly not on the current thread). If the specified timeout
     * elapses before the listener is notified, the listener will be notified with an {@link TimeoutException}. A caller may pass null to
     * specify no timeout.
     *
     * @param waitingForGlobalCheckpoint the global checkpoint the listener is waiting for
     * @param listener                   the listener
     * @param timeout                    the timeout
     */
    public void addGlobalCheckpointListener(
        final long waitingForGlobalCheckpoint,
        final GlobalCheckpointListeners.GlobalCheckpointListener listener,
        final TimeValue timeout
    ) {
        this.globalCheckpointListeners.add(waitingForGlobalCheckpoint, listener, timeout);
    }
    private void ensureSoftDeletesEnabled() {
        if (indexSettings.isSoftDeleteEnabled() == false) {
            String message = "retention leases requires soft deletes but "