apache/cassandra · error · ReadSizeAbortException
ReadSizeAbortException
Error message
ReadSizeAbortException
What it means
WarningsSnapshot.maybeAbort throws ReadSizeAbortException when the accumulated read material exceeds an abort threshold: either local read size (bytes of local reads) or row index-read size. The read is aborted server-side to prevent unbounded memory/CPU consumption on oversized reads.
Source
Thrown at src/java/org/apache/cassandra/service/reads/thresholds/WarningsSnapshot.java:114
@VisibleForTesting
WarningsSnapshot merge(WarningsSnapshot other)
{
if (other == null || other == EMPTY)
return this;
return WarningsSnapshot.create(tombstones.merge(other.tombstones),
localReadSize.merge(other.localReadSize),
rowIndexReadSize.merge(other.rowIndexReadSize),
indexReadSSTablesCount.merge(other.indexReadSSTablesCount));
}
public void maybeAbort(ReadCommand command, ConsistencyLevel cl, int received, int blockFor, boolean isDataPresent, Map<InetAddressAndPort, RequestFailureReason> failureReasonByEndpoint)
{
if (!tombstones.aborts.instances.isEmpty())
throw new TombstoneAbortException(tombstoneAbortMessage(tombstones.aborts.instances.size(), tombstones.aborts.maxValue, command.toCQLString()), tombstones.aborts.instances.size(), tombstones.aborts.maxValue, isDataPresent,
cl, received, blockFor, failureReasonByEndpoint);
if (!localReadSize.aborts.instances.isEmpty())
throw new ReadSizeAbortException(localReadSizeAbortMessage(localReadSize.aborts.instances.size(), localReadSize.aborts.maxValue, command.toCQLString()),
cl, received, blockFor, isDataPresent, failureReasonByEndpoint);
if (!rowIndexReadSize.aborts.instances.isEmpty())
throw new ReadSizeAbortException(rowIndexReadSizeAbortMessage(rowIndexReadSize.aborts.instances.size(), rowIndexReadSize.aborts.maxValue, command.toCQLString()),
cl, received, blockFor, isDataPresent, failureReasonByEndpoint);
if (!indexReadSSTablesCount.aborts.instances.isEmpty())
throw new QueryReferencesTooManyIndexesAbortException(tooManyIndexesReadAbortMessage(indexReadSSTablesCount.aborts.instances.size(), indexReadSSTablesCount.aborts.maxValue, command.toCQLString()),
indexReadSSTablesCount.aborts.instances.size(),
indexReadSSTablesCount.aborts.maxValue,
isDataPresent,
cl, received, blockFor, failureReasonByEndpoint);
}
@VisibleForTesting
public static String tombstoneAbortMessage(int nodes, long tombstones, String cql)
{
return String.format("%s nodes scanned over %s tombstones and aborted the query %s (see tombstone_failure_threshold)", nodes, tombstones, cql);View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Split the read: use token/partition ranges or LIMIT and paginate instead of reading a whole huge partition
- Raise local_read_size_fail_threshold / row_index_read_size_fail_threshold in cassandra.yaml if the reads are legitimate
- Redesign the data model to bucket large partitions into smaller ones
- Enable tracing on the query to see which partition/read triggers the size abort, then target that partition
Example fix
// before SELECT * FROM ks.events WHERE id = 'big-partition'; // after SELECT * FROM ks.events WHERE id = 'big-partition' AND bucket = 3; // bucketed partition
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: check partition size before a full read // shell: nodetool tablehistograms ks tbl — 'Partition size' p99 above local_read_size_warn_threshold signals risk
Try / catch
try {
return session.execute(widePartitionQuery);
} catch (e) {
if (e instanceof ReadSizeAbortException) {
logger.warn('read size abort; falling back to paginated/ranged read', e);
return paginatedRead(query, pageSize); // fallback strategy
}
throw e;
} Prevention
- Design partitions to stay well under read size thresholds (bucket large entities)
- Use pagination and LIMIT instead of full-partition reads
- Alert on read_size warn-threshold log lines before aborts occur
- Review thresholds after Cassandra upgrades since size-abort defaults may be new/stricter
When it happens
Trigger: A read command's local read bytes exceed local_read_size_abort_threshold, or row-index lookups exceed row_index_read_size_abort_threshold (e.g. querying a huge partition or doing many row-index jumps); awaitResults invokes maybeAbort with abort instances recorded.
Common situations: Single very large partitions (MBs/GBs) queried fully; thousands of rows fetched via secondary index; defaults too strict after upgrading (thresholds added in newer versions); analytics-style batch reads on wide partitions.
Related errors
- TombstoneAbortException
- %s (%s) must be greater than or equal to %s (%s)
- write_size_warn_threshold (%s) cannot be less than min_track
- write_tombstone_warn_threshold (%d) cannot be less than min_
- The warn threshold %d for %s_warn_threshold should be lower
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/01f8fef8a89f570b.
Report an issue: GitHub.