apache/cassandra · warning

Could not perform consistent fetch, downgrading to fetching…

Error message

Could not perform consistent fetch, downgrading to fetching from CMS peers.

What it means

PaxosBackedProcessor.fetchLogAndWait first tries a consistent fetch (Paxos read of the distributed log state). If that throws, it marks a consistency-downgrade metric and logs this warning, then falls back to fetching the log from CMS peers directly. The fetch still proceeds, just without the stronger consistency guarantee.

Solutions

  1. Check health of all CMS members and restore quorum (`nodetool cms show`, `nodetool status`).
  2. Investigate the attached Throwable; timeouts usually mean load or network issues.
  3. Ensure the fetch that follows succeeds; if it does, no further action needed.
  4. If downgrades are frequent, add capacity or review CMS replication factor placement.
Defensive patterns

Strategy: fallback

Validate before calling

// check CMS quorum health before consistent fetch
if (!metadata.fullCMSMembersAsReplicas().stream().allMatch(FailureDetector.instance::isAlive)) logger.debug("CMS quorum degraded; downgrade expected");

Try / catch

try { consistentFetch(); } catch (Throwable t) { peerFetch(); // documented downgrade path }

Prevention

When it happens

Trigger: A consistent log fetch fails — Paxos round timeout, a CMS member unavailable, or a commit/read failure on the log state table — triggering the catch block's downgrade path.

Common situations: CMS quorum degraded (a member down or slow); network latency between node and CMS; heavy load causing Paxos timeouts during large topology changes.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/b766d16214856e02. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/tcm/PaxosBackedProcessor.java:96

    @Override
    public ClusterMetadata fetchLogAndWait(Epoch waitFor, Retry retryPolicy)
    {
        ClusterMetadata metadata = log.waitForHighestConsecutive();

        // We can perform a local-only read without going through paxos subsystem in case of a single CMS node.
        if (metadata.fullCMSMembers().size() > 1)
        {
            try
            {
                // Attempt to perform a consistent fetch
                log.append(DistributedMetadataLogKeyspace.getLogState(metadata.epoch, true));
                return log.waitForHighestConsecutive();
            }
            catch (Throwable t)
            {
                JVMStabilityInspector.inspectThrowable(t);
                TCMMetrics.instance.fetchCMSLogConsistencyDowngrade.mark();
                logger.warn("Could not perform consistent fetch, downgrading to fetching from CMS peers.", t);
            }
        }

        EndpointsForRange replicas = metadata.fullCMSMembersAsReplicas();

        // We prefer to always perform a consistent fetch (i.e. Paxos read of the distributed log state table).
        // However, in some cases (specifically, during CMS membership changes) this may not be possible, as Paxos
        // relies on matching Participants, and there might be a mismatch during the membership change. In such
        // case, we allow inconsistent fetch. In other words, replay from local log of the majority of the CMS replicas.
        int blockFor = replicas.size() == 1 ? 1 : (replicas.size() / 2) + 1;

        Set<InetAddressAndPort> collected = new HashSet<>(blockFor);
        Set<FetchLogRequest> requests = new HashSet<>();
        AtomicReference<Epoch> highestSeen = new AtomicReference<>(metadata.epoch);

        for (Replica peer : replicas)
            requests.add(new FetchLogRequest(peer, MessagingService.instance(), metadata.epoch));

View on GitHub (pinned to 88fd0f6a0e)