apache/cassandra · error · IllegalArgumentException
Found 2 incompatible versions of column
Error message
Found 2 incompatible versions of column %s in %s.%s: one of type %s and one of type %s (but both types are incompatible)
What it means
ColumnMetadataVersionComparator orders successive versions of a column definition during schema diffing (used to build type change histories). One version's type is expected to be a supertype/subtype of the other (e.g. text -> blob-style widening). If neither type is compatible with the other, the schema history is internally inconsistent and an IllegalArgumentException is thrown rather than silently producing a wrong ordering.
Solutions
- Inspect the column's recorded type history in system_schema and fix it to a valid progression, or recreate the table and re-import data.
- Restore schema from a consistent snapshot (`nodetool snapshot` of system_schema or cqlsh DESCRIBE + full recreation).
- Ensure all nodes agree on schema; run full repair of schema tables / restart nodes to re-sync.
- Avoid direct edits or non-Cassandra tools writing to system_schema.
Example fix
// before: incompatible history written directly INSERT INTO system_schema.columns ... type 'int' then 'text' // after: valid widening progression only ALTER TABLE myks.mytable ALTER col TYPE blob; // int -> blob is a compatible widening
Defensive patterns
Strategy: try-catch
Validate before calling
// check recorded column type history is a compatible widening before diffing
if (!v1.type.asCQL3Type().isCompatibleWith(v2.type) && !v2.type.asCQL3Type().isCompatibleWith(v1.type)) throw new IllegalStateException("incompatible column history"); Try / catch
try { Collections.sort(versions, new ColumnMetadataVersionComparator()); } catch (IllegalArgumentException e) { restoreSchemaFromConsistentSnapshot(); } Prevention
- Never edit system_schema tables directly
- Only use supported ALTER type progressions
- Take schema snapshots before manual migrations
When it happens
Trigger: Schema tables containing a column whose recorded type history has two mutually incompatible types (e.g. int then text); hand-edited or partially migrated system_schema entries; reading schema history of a table that was altered in an unsupported way or by a foreign tool.
Common situations: Unsupported ALTER TABLE type changes or direct edits to system_schema; restoring schema tables from a different cluster; Cassandra version bugs in schema migration; third-party migration tools writing schema rows directly.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- All indexed columns should be included into the column…
- Constraint ' ' can be used only for columns of type but it…
- Invalid map literal for
- Unable to find table
- ACCESS TO DATACENTERS operations not supported by…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/6288d3eede356bcd.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/rows/ColumnMetadataVersionComparator.java:80
if (v1Type.isValueCompatibleWith(v2Type))
{
// Note: if both accept the same values, there is really no good way to prefer one over the other and so we
// consider them equal here. In practice, this mean we have 2 types that accepts the same values but are
// not equal. For internal types, TimestampType/DataType/LongType is, afaik, the only example, but as user
// can write custom types, who knows when this can happen. But excluding any user custom type weirdness
// (that would really be a bug of their type), such types should only differ in the way they sort, and as
// this method is only used for regular/static columns in practice, where sorting has no impact whatsoever,
// it shouldn't matter too much what we return here.
return v2Type.isValueCompatibleWith(v1Type) ? 0 : 1;
}
else if (v2Type.isValueCompatibleWith(v1Type))
{
return -1;
}
else
{
// Neither is a super type of the other: something is pretty wrong and we probably shouldn't ignore it.
throw new IllegalArgumentException(String.format("Found 2 incompatible versions of column %s in %s.%s: one " +
"of type %s and one of type %s (but both types are incompatible)",
v1.name, v1.ksName, v1.cfName, v1Type, v2Type));
}
}
}
View on GitHub (pinned to 88fd0f6a0e)