apache/cassandra · error · RowIndexEntryReadSizeTooLargeException

Query attempted to access a large RowIndexEntry estimated…

Error message

Query %s attempted to access a large RowIndexEntry estimated to be %d bytes in-memory (total entries: %d, total bytes: %d) but the max allowed is %s; query aborted  (see row_index_read_size_fail_threshold)

What it means

Thrown as RowIndexEntryReadSizeTooLargeException when deserializing a RowIndexEntry for a query would exceed the row_index_read_size_fail_threshold for estimated in-memory size. This guards the coordinator against huge row indexes (very wide partitions) that could exhaust heap.

Solutions

  1. Lower data granularity so partitions are smaller (better partition key design), or raise row_index_read_size_fail_threshold if the workload legitimately needs large partitions
  2. Rewrite queries to narrow the partition/clustering slice so fewer index entries are needed
  3. Run compaction/cleanup and monitor with the warn threshold (row_index_read_size_warn_threshold) to find offending partitions

Example fix

// cassandra.yaml
// before
row_index_read_size_fail_threshold: 64KiB
// after
row_index_read_size_fail_threshold: 512KiB
Defensive patterns

Strategy: validation

Validate before calling

// Track partition sizes before they grow unbounded
long partitionSize = estimatePartitionSize(keyspace, table, partitionKey);
long threshold = Config.getRowIndexReadSizeFailThreshold().toBytes();
if (partitionSize > threshold) {
    logger.warn("Partition {} exceeds fail threshold {}; reshard data", partitionKey, threshold);
}

Try / catch

try { rs = session.execute(query); }
catch (RowIndexEntryReadSizeTooLargeException e) {
    logger.warn("Aborted read of oversized partition: {}", e.getMessage());
    // narrow the query or redesign the partition key
}

Prevention

When it happens

Trigger: A query touches a partition whose serialized row index (many indexInfo blocks / entries) estimates above the fail threshold bytes when deserialized; checkSize is invoked from RowIndexEntry.deserialize with the read command.

Common situations: Extremely wide partitions (millions of rows per partition); too-low row_index_read_size_fail_threshold in cassandra.yaml; queries without partition range limits hitting unbounded partitions.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/io/sstable/format/big/RowIndexEntry.java:408

            DataStorageSpec.LongBytesBound warnThreshold = DatabaseDescriptor.getRowIndexReadSizeWarnThreshold();
            DataStorageSpec.LongBytesBound failThreshold = DatabaseDescriptor.getRowIndexReadSizeFailThreshold();
            if (warnThreshold == null && failThreshold == null)
                return;

            long estimatedMemory = estimateMaterializedIndexSize(entries, bytes);
            if (tableMetrics != null)
                tableMetrics.rowIndexSize.update(estimatedMemory);

            if (failThreshold != null && estimatedMemory > failThreshold.toBytes())
            {
                String msg = String.format("Query %s attempted to access a large RowIndexEntry estimated to be %d bytes " +
                                           "in-memory (total entries: %d, total bytes: %d) but the max allowed is %s;" +
                                           " query aborted  (see row_index_read_size_fail_threshold)",
                                           command.toCQLString(), estimatedMemory, entries, bytes, failThreshold);
                MessageParams.remove(ParamType.ROW_INDEX_READ_SIZE_WARN);
                MessageParams.add(ParamType.ROW_INDEX_READ_SIZE_FAIL, estimatedMemory);

                throw new RowIndexEntryReadSizeTooLargeException(msg);
            }
            else if (warnThreshold != null && estimatedMemory > warnThreshold.toBytes())
            {
                // use addIfLarger rather than add as a previous partition may be larger than this one
                Long current = MessageParams.get(ParamType.ROW_INDEX_READ_SIZE_WARN);
                if (current == null || current.compareTo(estimatedMemory) < 0)
                    MessageParams.add(ParamType.ROW_INDEX_READ_SIZE_WARN, estimatedMemory);
            }
        }

        private static long estimateMaterializedIndexSize(int entries, int bytes)
        {
            long overhead = IndexInfo.EMPTY_SIZE
                            + ArrayClustering.EMPTY_SIZE
                            + DeletionTime.EMPTY_SIZE;

            return (overhead * entries) + bytes;
        }

View on GitHub (pinned to 88fd0f6a0e)