{"record":{"id":"70bbe4a1390ae337","repo":"apache/cassandra","slug":"learned-about-epoch-s-from-s-but-could-not-fetc","errorCode":null,"errorMessage":"Learned about epoch %s from %s, but could not fetch log.","messagePattern":"Learned about epoch (.+?) from (.+?), but could not fetch log\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/tcm/ClusterMetadataService.java","lineNumber":925,"sourceCode":"            logger.debug(\"Fetch metadata log from peer was requested, but log processing is paused\");\n            return metadata;\n        }\n\n        return peerLogFetcher.fetchLogEntriesAndWait(from, awaitAtLeast);\n    }\n\n    public Future<ClusterMetadata> fetchLogFromPeerOrCMSAsync(ClusterMetadata metadata, InetAddressAndPort from, Epoch awaitAtLeast)\n    {\n        AsyncPromise<ClusterMetadata> future = new AsyncPromise<>();\n        ScheduledExecutors.optionalTasks.submit(() -> {\n            try\n            {\n                future.setSuccess(fetchLogFromPeerOrCMS(metadata, from, awaitAtLeast));\n            }\n            catch (Throwable t)\n            {\n                JVMStabilityInspector.inspectThrowable(t);\n                logger.warn(String.format(\"Learned about epoch %s from %s, but could not fetch log.\", awaitAtLeast, from), t);\n                future.setFailure(t);\n            }\n        });\n        return future;\n    }\n\n    public boolean maybeFetchLogFromPeerOrCMSAsync(MessageDelivery messaging, Message<?> message, Runnable onFetchSuccess)\n    {\n        ClusterMetadata metadata = metadata();\n        if (metadata.epoch.isEqualOrAfter(metadata.epoch))\n            return false;\n        Future<ClusterMetadata> f = fetchLogFromPeerOrCMSAsync(metadata, message.from(), message.epoch());\n        f.addCallback((success, failure) -> {\n            if (failure != null) messaging.respondWithFailure(RequestFailure.UNKNOWN, message);\n            else                 message.verb().stage.execute(onFetchSuccess);\n        });\n        return true;\n    }","sourceCodeStart":907,"sourceCodeEnd":943,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/ClusterMetadataService.java#L907-L943","documentation":"When a node learns about a new epoch from a peer but fails to fetch the corresponding log entries, ClusterMetadataService logs this warning and completes the future with the failure. The node knows a newer epoch exists but cannot advance to it.","triggerScenarios":"A gossip message or callback notifies the node about epoch `awaitAtLeast` from peer `from`; the subsequent fetchLogFromPeerOrCMS call throws (peer down, timeouts, serialization failure), so the future is failed.","commonSituations":"Peer briefly unreachable during topology change; CMS overloaded or restarting; network flaps during bootstrap or decommission; retries normally succeed.","solutions":["Check connectivity to the reporting peer and CMS members.","Inspect the attached Throwable for the root cause (timeout, refused connection, serialization).","Verify the CMS is healthy and quorum-reachable; restart a bad CMS member if needed.","Retries: the fetch will be re-attempted on the next epoch notification or retry loop."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// probe peer reachability before fetching\nif (!FailureDetector.instance.isAlive(from)) logger.debug(\"skipping fetch, peer {} down\", from);","typeGuard":null,"tryCatchPattern":"future.addEventListener(f -> { if (f.cause() != null) scheduleRetryFetch(awaitAtLeast); });","preventionTips":["Keep CMS members quorum-reachable","Monitor epoch-notification fetch failures","Ensure RPC timeouts accommodate large log gaps"],"tags":["fetch-log","peer-fetch","network"],"backgroundTag":"network-request-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}