{"record":{"id":"74367ed04311ae82","repo":"apache/cassandra","slug":"readtimeoutexception","errorCode":null,"errorMessage":"ReadTimeoutException","messagePattern":"ReadTimeoutException","errorType":"exception","errorClass":"ReadTimeoutException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/reads/AbstractReadExecutor.java","lineNumber":476,"sourceCode":"            }\n        }\n    }\n\n    public void awaitReadRepair() throws ReadTimeoutException\n    {\n        try\n        {\n            readRepair.awaitReads();\n        }\n        catch (ReadTimeoutException e)\n        {\n            if (Tracing.isTracing())\n                Tracing.trace(\"Timed out waiting on digest mismatch repair requests\");\n            else\n                logger.trace(\"Timed out waiting on digest mismatch repair requests\");\n            // the caught exception here will have CL.ALL from the repair command,\n            // not whatever CL the initial command was at (CASSANDRA-7947)\n            throw new ReadTimeoutException(replicaPlan().consistencyLevel(), handler.replicaPlan().readQuorum() - 1, handler.replicaPlan().readQuorum(), true);\n        }\n    }\n\n    boolean isDone()\n    {\n        return result != null;\n    }\n\n    public void maybeSendAdditionalDataRequests()\n    {\n        if (isDone())\n            return;\n\n        readRepair.maybeSendAdditionalReads();\n    }\n\n    public PartitionIterator getResult() throws ReadFailureException, ReadTimeoutException\n    {","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/reads/AbstractReadExecutor.java#L458-L494","documentation":"After a digest mismatch, the read executor waits for read-repair responses at CL.ALL; awaitReadRepair throws ReadTimeoutException if the repair responses don't arrive in time. Per CASSANDRA-7947 the exception reports the read-quorum counts, so the reported consistency/counts reflect the repair command, not the original read CL.","triggerScenarios":"Digest mismatch triggers read repair, but at least one replica holding the repair response fails to reply within read_rpc_timeout; slow/hung replicas, GC pauses, or network issues during the repair round.","commonSituations":"Reads on tables with frequent inconsistencies (hinted handoff backlog, failing replica), timeouts under heavy read load, multi-DC latency during repair.","solutions":["Check replica health and network; restart or replace unresponsive replicas","Increase read_rpc_timeout in cassandra.yaml if repairs are slow but progressing","Run nodetool repair to restore consistency so fewer digests mismatch","Investigate why replicas diverge (dropped mutations, failed writes) via logs"],"exampleFix":"// before\ncassandra.yaml: read_rpc_timeout: 5000\n// after\ncassandra.yaml: read_rpc_timeout: 15000\n(restart required)","handlingStrategy":"retry","validationCode":"// preflight: ensure all read replicas are alive for the chosen CL\nlong alive = replicaPlan.readReplicas().stream().filter(fd::isAlive).count();\nif (alive < replicaPlan.readQuorum()) throw new UnavailableException(cl, replicaPlan.readQuorum(), (int) alive);","typeGuard":null,"tryCatchPattern":"try { rs = session.execute(readQuery); }\ncatch (ReadTimeoutException e) { backoff(); retryWithLowerCLorFail(); }","preventionTips":["Run regular (nodetool) repair to minimize digest mismatches","Keep read_rpc_timeout generous relative to repair latency","Investigate persistently inconsistent replicas","Reduce read load spikes that slow repair rounds"],"tags":["timeout","read-repair","consistency"],"backgroundTag":"request-timeout","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"}