apache/cassandra · critical · CorruptSSTableException
Cannot open ; partitioner does not match system partitioner…
Error message
Cannot open %s; partitioner %s does not match system partitioner %s. Note that the default partitioner starting with Cassandra 1.2 is Murmur3Partitioner, so you will need to edit that to match your old partitioner if upgrading.
What it means
validatePartitioner() compares the partitioner recorded in the SSTable's Validation metadata (Statistics.db) with the partitioner of the table being opened. A mismatch means the SSTable's token ordering is incompatible with the table's partitioner, so it throws CorruptSSTableException pointing at the stats component, with guidance about Murmur3Partitioner being the default since 1.2.
Solutions
- Set the table/cluster partitioner to match the SSTable's (edit partitioner in cassandra.yaml or table metadata) — only viable if reconfiguring is acceptable
- Rewrite the SSTables with sstableloader into a cluster/table using the correct partitioner
- Verify the recorded partitioner via sstablemetadata <data-file> before loading
- If truly incompatible, discard and rebuild the data via repair from replicas
Example fix
// before: cassandra.yaml with leftover old partitioner partitioner: org.apache.cassandra.dht.RandomPartitioner // after partitioner: org.apache.cassandra.dht.Murmur3Partitioner
Defensive patterns
Strategy: validation
Validate before calling
// compare partitioners before loading
String sstablePartitioner = sstablemetadata(dataFile).partitioner;
String tablePartitioner = metadata.partitioner.getClass().getCanonicalName();
if (!sstablePartitioner.equals(tablePartitioner)) { fixConfigOrRewrite(); } Try / catch
try { SSTableReader.open(descriptor, components, metadata); }
catch (CorruptSSTableException e) {
if (e.getMessage().contains("partitioner") && e.getMessage().contains("does not match")) {
logger.error("Partitioner mismatch for {}", descriptor);
alignPartitionerConfigOrUseSstableloader();
} else throw e;
} Prevention
- Keep partitioner: Murmur3Partitioner in cassandra.yaml on all modern clusters
- Check sstablemetadata partitioner before loading foreign SSTables
- Never change partitioner on existing data; migrate via sstableloader instead
- Ensure all nodes in a cluster use the same partitioner
When it happens
Trigger: Opening/loading an SSTable whose ValidationMetadata.partitioner differs from metadata.partitioner — e.g. loading SSTables written under RandomPartitioner/ByteOrderedPartitioner into a Murmur3 table, or cassandra.yaml partitioner changed between cluster versions.
Common situations: Upgrades from pre-1.2 clusters with edited/unchanged partitioner settings; copying SSTables between clusters configured with different partitioners; pointing tools at foreign SSTable directories.
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
- Partitioner does not match validation metadata
- 3
- A range supplied to SSTableCursorReader ends before it…
- Aborting SSTable index flush for
- Can't import sstable
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ebf1b93a2dd584e7.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/io/sstable/format/SSTableReaderLoadingBuilder.java:130
throw new CorruptSSTableException(ex, descriptor.baseFile());
}
}
public abstract KeyReader buildKeyReader(TableMetrics tableMetrics) throws IOException;
protected abstract void openComponents(B builder, SSTable.Owner owner, boolean validate, boolean online) throws IOException;
/**
* Check if sstable is created using same partitioner.
* Partitioner can be null, which indicates older version of sstable or no stats available.
* In that case, we skip the check.
*/
protected void validatePartitioner(TableMetadata metadata, ValidationMetadata validationMetadata)
{
String partitionerName = metadata.partitioner.getClass().getCanonicalName();
if (validationMetadata != null && !partitionerName.equals(validationMetadata.partitioner))
{
throw new CorruptSSTableException(new IOException(String.format("Cannot open %s; partitioner %s does not match system partitioner %s. " +
"Note that the default partitioner starting with Cassandra 1.2 is Murmur3Partitioner, " +
"so you will need to edit that to match your old partitioner if upgrading.",
descriptor, validationMetadata.partitioner, partitionerName)),
descriptor.fileFor(Components.STATS));
}
}
private TableMetadataRef resolveTableMetadataRef()
{
TableMetadataRef metadata;
if (descriptor.cfname.contains(SECONDARY_INDEX_NAME_SEPARATOR))
{
int i = descriptor.cfname.indexOf(SECONDARY_INDEX_NAME_SEPARATOR);
String indexName = descriptor.cfname.substring(i + 1);
metadata = Schema.instance.getIndexMetadata(descriptor.ksname, indexName).map(m -> m.ref).orElse(null);
if (metadata == null)
throw new AssertionError("Could not find index metadata for index cf " + i);
}View on GitHub (pinned to 88fd0f6a0e)