apache/cassandra · warning
Changing from TimestampType to DateType is allowed, but be…
Error message
Changing from TimestampType to DateType is allowed, but be wary that they sort differently for pre-unix-epoch timestamps (negative timestamp values) and thus this change will corrupt your data if you have such negative timestamp. There is no reason to switch from DateType to TimestampType except if you were using DateType in the first place and switched to TimestampType by mistake.
What it means
DateType.isCompatibleWith permits schema evolution from TimestampType back to DateType because their binary encodings are compatible (both 8-byte values), but they order bytes differently for negative (pre-1970) timestamps. Cassandra warns because changing comparator order corrupts sorted data on disk if any negative timestamp values exist.
Solutions
- First confirm no negative (pre-unix-epoch) timestamp values exist: SELECT the column and check for dates before 1970-01-01
- If negative values exist, migrate data to a new column/table instead of altering the type in place
- If values are safe, re-run the ALTER and ignore the warning
- Keep the type as TimestampType if unsure - the warning is the safer path
Example fix
// before: blindly alter ALTER TABLE events ALTER occurred_at TYPE date; // after: verify first SELECT occurred_at FROM events WHERE occurred_at < 0 LIMIT 1 ALLOW FILTERING; // none -> safe to alter
Defensive patterns
Strategy: validation
Validate before calling
// reject the schema change if pre-epoch values may exist
ResultSet rs = session.execute("SELECT pk FROM t WHERE ts_col < 0 ALLOW FILTERING");
if (!rs.isEmpty()) throw new IllegalStateException("Pre-1970 timestamps present; do not alter to date"); Prevention
- Audit for negative timestamps before DateType/TimestampType swaps
- Prefer timestamp for all new schemas
- Never alternate types back and forth across migrations
- Test schema changes on a staging copy of data
When it happens
Trigger: Executing ALTER TABLE ... ALTER <column> TYPE date (or updating a comparator/validation class) on a column previously of TimestampType (org.apache.cassandra.db.marshal.TimestampType) when the table uses DateType ordering.
Common situations: Migrating legacy schema where a column was accidentally created as timestamp and the operator wants date semantics; schema imports from old clusters (pre-2.0 thrift metadata).
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Changing from DateType to TimestampType is allowed, but be…
- ACCESS TO DATACENTERS operations not supported by…
- Aggregate ' ' already exists
- All indexed columns should be included into the column…
- ALREADY_EXISTS
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/3ed80fbfaefa2ccc.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/marshal/DateType.java:113
parsed.getClass().getSimpleName(), parsed));
}
}
@Override
public String toJSONString(ByteBuffer buffer, ProtocolVersion protocolVersion)
{
return '"' + TimestampSerializer.getJsonDateFormatter().format(TimestampSerializer.instance.deserialize(buffer).toInstant()) + '"';
}
@Override
public boolean isCompatibleWith(AbstractType<?> previous)
{
if (super.isCompatibleWith(previous))
return true;
if (previous instanceof TimestampType)
{
logger.warn("Changing from TimestampType to DateType is allowed, but be wary that they sort differently for pre-unix-epoch timestamps "
+ "(negative timestamp values) and thus this change will corrupt your data if you have such negative timestamp. There is no "
+ "reason to switch from DateType to TimestampType except if you were using DateType in the first place and switched to "
+ "TimestampType by mistake.");
return true;
}
return false;
}
@Override
public boolean isValueCompatibleWithInternal(AbstractType<?> otherType)
{
return this == otherType || otherType == TimestampType.instance || otherType == LongType.instance;
}
@Override
public CQL3Type asCQL3Type()
{View on GitHub (pinned to 88fd0f6a0e)