apache/cassandra · error · IOException

Cannot read index summary because min_index_interval…

Error message

Cannot read index summary because min_index_interval changed from %d to %d.

What it means

Thrown by IndexSummary.deserialize when the min_index_interval stored in the summary file differs from the table's currently configured min_index_interval. The index summary format is tied to the interval, so Cassandra aborts loading and rebuilds/validates rather than producing wrong index entries.

Solutions

  1. Run `nodetool clearsnapshot`-style removal of stale summaries or run upgradesstables -a to rebuild summaries with the current interval
  2. Revert the min_index_interval change in the table schema to match the sstables
  3. Use `nodetool relocatesstables`/offheap_object cleanup or delete the Summary.db component so it regenerates on startup
  4. Move sstables only between tables with identical compaction/index settings

Example fix

// before: interval changed under existing sstables
ALTER TABLE ks.t WITH min_index_interval = 256;
// after: rebuild summaries first
nodetool upgradesstables ks t --include-all-sstables; then ALTER TABLE ks.t WITH min_index_interval = 256;
Defensive patterns

Strategy: fallback

Validate before calling

// read min_index_interval from summary header before full load; if it differs, plan a rebuild
int stored = headerStream.readInt(); if (stored != schema.params.minIndexInterval) triggerSummaryRebuild(descriptor);

Try / catch

try { summary.deserialize(in, partitioner, minInterval, maxInterval); } catch (IOException e) { rebuildIndexSummary(descriptor); }

Prevention

When it happens

Trigger: Loading an sstable whose summary was written with a different min_index_interval than the table's current value (e.g. min_index_interval was changed in the table schema, or restored sstables from a cluster with different settings).

Common situations: Altering a table's min_index_interval while old sstables exist, restoring sstables from a backup of a differently configured table, copying sstables between clusters with mismatched schemas.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummary.java:431

            // In this case adding X to each of the offsets.
            int baseOffset = t.offsetCount * 4;
            for (int i = 0 ; i < t.offsetCount ; i++)
            {
                int offset = t.offsets.getInt(i * 4) + baseOffset;
                // our serialization format for this file uses native byte order, so if this is different to the
                // default Java serialization order (BIG_ENDIAN) we have to reverse our bytes
                offset = Integer.reverseBytes(offset);
                out.writeInt(offset);
            }
            out.write(t.entries, 0, t.entriesLength);
        }

        public <T extends InputStream & DataInputPlus> IndexSummary deserialize(T in, IPartitioner partitioner, int expectedMinIndexInterval, int maxIndexInterval) throws IOException
        {
            int minIndexInterval = in.readInt();
            if (minIndexInterval != expectedMinIndexInterval)
            {
                throw new IOException(String.format("Cannot read index summary because min_index_interval changed from %d to %d.",
                                                    minIndexInterval, expectedMinIndexInterval));
            }

            int offsetCount = in.readInt();
            long offheapSize = in.readLong();
            int samplingLevel = in.readInt();
            int fullSamplingSummarySize = in.readInt();

            int effectiveIndexInterval = (int) Math.ceil((BASE_SAMPLING_LEVEL / (double) samplingLevel) * minIndexInterval);
            if (effectiveIndexInterval > maxIndexInterval)
            {
                throw new IOException(String.format("Rebuilding index summary because the effective index interval (%d) is higher than" +
                                                    " the current max index interval (%d)", effectiveIndexInterval, maxIndexInterval));
            }

            Memory offsets = Memory.allocate(offsetCount * 4);
            Memory entries = Memory.allocate(offheapSize - offsets.size());
            try

View on GitHub (pinned to 88fd0f6a0e)