### CI Link

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

### Repro line

./gradlew ':server:internalClusterTest' --tests "org.elasticsearch.recovery.RelocationIT.testRelocationEstablishedPeerRecoveryRetentionLeases" -Dtests.seed=48DD4597C7EC8FF7 -Dtests.locale=es-PA -Dtests.timezone=Europe/Bucharest -Druntime.java=17	

### Does it reproduce?

No

### Applicable branches

master

### Failure history

https://gradle-enterprise.elastic.co/scans/tests?search.relativeStartTime=P7D&search.timeZoneId=Europe/Bucharest&tests.container=org.elasticsearch.recovery.RelocationIT&tests.sortField=FAILED&tests.test=testRelocationEstablishedPeerRecoveryRetentionLeases&tests.unstableOnly=true

### Failure excerpt

  1> [2022-03-14T13:43:38,122][INFO ][o.e.r.RelocationIT       ] [testRelocationEstablishedPeerRecoveryRetentionLeases] [RelocationIT#testRelocationEstablishedPeerRecoveryRetentionLeases]: cleaned up after test
  2> REPRODUCE WITH: ./gradlew ':server:internalClusterTest' --tests "org.elasticsearch.recovery.RelocationIT.testRelocationEstablishedPeerRecoveryRetentionLeases" -Dtests.seed=48DD4597C7EC8FF7 -Dtests.locale=es-PA -Dtests.timezone=Europe/Bucharest -Druntime.java=17
  2> java.lang.AssertionError: 
    Expected: an empty collection
         but: <[LEAK: resource was not cleaned up before it was garbage-collected.
    Recent access records: 
    Created at:
    	org.elasticsearch.common.util.MockPageCacheRecycler.wrap(MockPageCacheRecycler.java:32)
    	org.elasticsearch.common.util.MockPageCacheRecycler.bytePage(MockPageCacheRecycler.java:72)
    	org.elasticsearch.transport.BytesRefRecycler.obtain(BytesRefRecycler.java:27)
    	org.elasticsearch.common.io.stream.RecyclerBytesStreamOutput.ensureCapacityFromPosition(RecyclerBytesStreamOutput.java:211)
    	org.elasticsearch.common.io.stream.RecyclerBytesStreamOutput.ensureCapacity(RecyclerBytesStreamOutput.java:202)
    	org.elasticsearch.common.io.stream.RecyclerBytesStreamOutput.writeBytes(RecyclerBytesStreamOutput.java:77)
    	org.elasticsearch.common.io.Streams$FlushOnCloseOutputStream.writeBytes(Streams.java:274)
    	org.elasticsearch.common.io.stream.StreamOutput.write(StreamOutput.java:482)
    	java.base/java.io.OutputStream.write(OutputStream.java:127)
    	org.elasticsearch.common.compress.DeflateCompressor.threadLocalOutputStream(DeflateCompressor.java:179)
    	org.elasticsearch.cluster.coordination.PublicationTransportHandler.serializeDiffClusterState(PublicationTransportHandler.java:266)
    	org.elasticsearch.cluster.coordination.PublicationTransportHandler$PublicationContext.lambda$buildDiffAndSerializeStates$2(PublicationTransportHandler.java:329)
    	java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220)
    	org.elasticsearch.cluster.coordination.PublicationTransportHandler$PublicationContext.buildDiffAndSerializeStates(PublicationTransportHandler.java:327)
    	org.elasticsearch.cluster.coordination.PublicationTransportHandler.newPublicationContext(PublicationTransportHandler.java:213)
    	org.elasticsearch.cluster.coordination.Coordinator.publish(Coordinator.java:1368)
    	org.elasticsearch.cluster.service.MasterService.publish(MasterService.java:416)
    	org.elasticsearch.cluster.service.MasterService.runTasks(MasterService.java:309)
    	org.elasticsearch.cluster.service.MasterService$Batcher.run(MasterService.java:153)
    	org.elasticsearch.cluster.service.TaskBatcher.runIfNotProcessed(TaskBatcher.java:114)
    	org.elasticsearch.cluster.service.TaskBatcher$BatchedTask.run(TaskBatcher.java:170)
    	org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:717)
    	org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.runAndClean(PrioritizedEsThreadPoolExecutor.java:260)
    	org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedEsThreadPoolExecutor.java:223)
    	java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    	java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    	java.base/java.lang.Thread.run(Thread.java:833)]>
        at __randomizedtesting.SeedInfo.seed([48DD4597C7EC8FF7:886D486B4E0323C8]:0)
        at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
        at org.junit.Assert.assertThat(Assert.java:956)
        at org.junit.Assert.assertThat(Assert.java:923)
        at org.elasticsearch.test.ESTestCase.checkStaticState(ESTestCase.java:639)
        at org.elasticsearch.test.ESTestCase.after(ESTestCase.java:427)
        at jdk.internal.reflect.GeneratedMethodAccessor22.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at com.carrotsearch.randomizedtesting.RandomizedRunner.invoke(RandomizedRunner.java:1758)
        at com.carrotsearch.randomizedtesting.RandomizedRunner$10.evaluate(RandomizedRunner.java:1004)
        at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
        at org.apache.lucene.tests.util.TestRuleSetupTeardownChained$1.evaluate(TestRuleSetupTeardownChained.java:44)
        at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
        at org.apache.lucene.tests.util.TestRuleThreadAndTestName$1.evaluate(TestRuleThreadAndTestName.java:45)
        at org.apache.lucene.tests.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(TestRuleIgnoreAfterMaxFailures.java:60)
        at org.apache.lucene.tests.util.TestRuleMarkFailure$1.evaluate(TestRuleMarkFailure.java:44)
        at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
        at com.carrotsearch.randomizedtesting.ThreadLeakControl$StatementRunner.run(ThreadLeakControl.java:375)
        at com.carrotsearch.randomizedtesting.ThreadLeakControl.forkTimeoutingTask(ThreadLeakControl.java:824)
        at com.carrotsearch.randomizedtesting.ThreadLeakControl$3.evaluate(ThreadLeakControl.java:475)
        at com.carrotsearch.randomizedtesting.RandomizedRunner.runSingleTest(RandomizedRunner.java:955)
        at com.carrotsearch.randomizedtesting.RandomizedRunner$5.evaluate(RandomizedRunner.java:840)
        at com.carrotsearch.randomizedtesting.RandomizedRunner$6.evaluate(RandomizedRunner.java:891)
        at com.carrotsearch.randomizedtesting.RandomizedRunner$7.evaluate(RandomizedRunner.java:902)
        at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
        at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
        at org.apache.lucene.tests.util.TestRuleStoreClassName$1.evaluate(TestRuleStoreClassName.java:38)
        at com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40)
        at com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40)
        at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
        at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
        at org.apache.lucene.tests.util.TestRuleAssertionsRequired$1.evaluate(TestRuleAssertionsRequired.java:53)
        at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
        at org.apache.lucene.tests.util.TestRuleMarkFailure$1.evaluate(TestRuleMarkFailure.java:44)
        at org.apache.lucene.tests.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(TestRuleIgnoreAfterMaxFailures.java:60)
        at org.apache.lucene.tests.util.TestRuleIgnoreTestSuites$1.evaluate(TestRuleIgnoreTestSuites.java:47)
        at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
        at com.carrotsearch.randomizedtesting.ThreadLeakControl$StatementRunner.run(ThreadLeakControl.java:375)
        at com.carrotsearch.randomizedtesting.ThreadLeakControl.lambda$forkTimeoutingTask$0(ThreadLeakControl.java:831)
        at java.base/java.lang.Thread.run(Thread.java:833)
  1> [2022-03-14T13:43:38,149][INFO ][o.e.r.RelocationIT       ] [testIndexSearchAndRelocateConcurrently] before test
  1> [2022-03-14T13:43:38,149][INFO ][o.e.r.RelocationIT       ] [testIndexSearchAndRelocateConcurrently] [RelocationIT#testIndexSearchAndRelocateConcurrently]: setting up test
  1> [2022-03-14T13:43:38,150][INFO ][o.e.t.InternalTestCluster] [testIndexSearchAndRelocateConcurrently] Setup InternalTestCluster [TEST-TEST_WORKER_VM=[471]-CLUSTER_SEED=[-2805428162336455921]-HASH=[1322FA3E367]-cluster] with seed [D9111DF33D0F030F] using [0] dedicated masters, [0] (data) nodes and [0] coord only nodes (master nodes are [auto-managed])
test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java
@Override
                public void handleResponse(Version1Response response) {
                    assertThat(response.value1, equalTo(1));
                    assertThat(response.value2, equalTo(0)); 
                }
                @Override
                public void handleException(TransportException exp) {
                    logger.error("Unexpected failure", exp);
                    fail("got exception instead of a response: " + exp.getMessage());
                }
            }
        ).get();
        assertThat(version1Response.value1, equalTo(1));
        assertThat(version1Response.value2, equalTo(0));
    }
    public void testVersionFrom1to1() throws Exception {
        serviceB.registerRequestHandler("internal:version", ThreadPool.Names.SAME, Version1Request::new, (request, channel, task) -> {
            assertThat(request.value1, equalTo(1));
            assertThat(request.value2, equalTo(2));
            Version1Response response = new Version1Response(1, 2);
            channel.sendResponse(response);
            assertEquals(version1, channel.getVersion());
        });
        Version1Request version1Request = new Version1Request();
        version1Request.value1 = 1;
        version1Request.value2 = 2;
        Version1Response version1Response = submitRequest(
            serviceB,
            nodeB,
            "internal:version",