apache/cassandra · warning
Learned about epoch from , but could not fetch log.
Error message
Learned about epoch %s from %s, but could not fetch log.
What it means
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.
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.
Defensive patterns
Strategy: retry
Validate before calling
// probe peer reachability before fetching
if (!FailureDetector.instance.isAlive(from)) logger.debug("skipping fetch, peer {} down", from); Try / catch
future.addEventListener(f -> { if (f.cause() != null) scheduleRetryFetch(awaitAtLeast); }); Prevention
- Keep CMS members quorum-reachable
- Monitor epoch-notification fetch failures
- Ensure RPC timeouts accommodate large log gaps
When it happens
Trigger: 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.
Common situations: Peer briefly unreachable during topology change; CMS overloaded or restarting; network flaps during bootstrap or decommission; retries normally succeed.
Related errors
- Could not fetch log entries from peer, remote =
- Unable to fetch log entries from
- Addresses differ: !=
- Already released
- Attempted to reference an already released SharedByteBuffer
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/70bbe4a1390ae337.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/ClusterMetadataService.java:925
logger.debug("Fetch metadata log from peer was requested, but log processing is paused");
return metadata;
}
return peerLogFetcher.fetchLogEntriesAndWait(from, awaitAtLeast);
}
public Future<ClusterMetadata> fetchLogFromPeerOrCMSAsync(ClusterMetadata metadata, InetAddressAndPort from, Epoch awaitAtLeast)
{
AsyncPromise<ClusterMetadata> future = new AsyncPromise<>();
ScheduledExecutors.optionalTasks.submit(() -> {
try
{
future.setSuccess(fetchLogFromPeerOrCMS(metadata, from, awaitAtLeast));
}
catch (Throwable t)
{
JVMStabilityInspector.inspectThrowable(t);
logger.warn(String.format("Learned about epoch %s from %s, but could not fetch log.", awaitAtLeast, from), t);
future.setFailure(t);
}
});
return future;
}
public boolean maybeFetchLogFromPeerOrCMSAsync(MessageDelivery messaging, Message<?> message, Runnable onFetchSuccess)
{
ClusterMetadata metadata = metadata();
if (metadata.epoch.isEqualOrAfter(metadata.epoch))
return false;
Future<ClusterMetadata> f = fetchLogFromPeerOrCMSAsync(metadata, message.from(), message.epoch());
f.addCallback((success, failure) -> {
if (failure != null) messaging.respondWithFailure(RequestFailure.UNKNOWN, message);
else message.verb().stage.execute(onFetchSuccess);
});
return true;
}View on GitHub (pinned to 88fd0f6a0e)