{"record":{"id":"80b3e5f4e0ae0b2f","repo":"apache/cassandra","slug":"a-tombstone-should-not-have-a-value","errorCode":null,"errorMessage":"A tombstone should not have a value","messagePattern":"A tombstone should not have a value","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/schema/ColumnMetadata.java","lineNumber":662,"sourceCode":"    }\n\n    public boolean isSimple()\n    {\n        return !isComplex();\n    }\n\n    public CellPath.Serializer cellPathSerializer()\n    {\n        // Collections are our only complex so far, so keep it simple\n        return CollectionType.cellPathSerializer;\n    }\n\n    public <V> void validateCell(Cell<V> cell)\n    {\n        if (cell.isTombstone())\n        {\n            if (cell.valueSize() > 0)\n                throw new MarshalException(\"A tombstone should not have a value\");\n            if (cell.path() != null)\n                validateCellPath(cell.path());\n        }\n        else if(type.isUDT())\n        {\n            // To validate a non-frozen UDT field, both the path and the value\n            // are needed, the path being an index into an array of value types.\n            ((UserType)type).validateCell(cell);\n        }\n        else\n        {\n            type.validateCellValue(cell.value(), cell.accessor());\n            if (cell.path() != null)\n                validateCellPath(cell.path());\n        }\n    }\n\n    private void validateCellPath(CellPath path)","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/schema/ColumnMetadata.java#L644-L680","documentation":"ColumnMetadata.validateCell() enforces that a Cell representing a tombstone (liveness deletion info present) carries an empty value. A tombstone whose serialized value size is greater than zero indicates corrupted or invalidly written data, so MarshalException is thrown during validation.","triggerScenarios":"Reading or writing a partition where a cell is marked as a tombstone but has a non-empty value — typically from corrupt SSTables, a coordinator/replica version or serialization bug, or hand-crafted mutation data via internal APIs.","commonSituations":"During compaction/validation reads after a crash or corrupted commit log; replaying WAL/mutation data produced by a buggy client using the internal API; after upgrading across versions with a serialization change.","solutions":["Run nodetool scrub on the affected table to drop corrupt cells","Restore the affected SSTables/backups or run repair to obtain clean copies from healthy replicas","Check cluster version consistency and client write paths that build Cells directly; re-produce with a repro test if writing via internal APIs"],"exampleFix":"// before (internal API misuse)\nCell<v> bad = BufferCell.live(column, ts, value, del(\"2024-01-01T00:00:00Z\"));\n// after\nCell<v> ok = BufferCell.tombstone(column.deletionTime(), ts, path); // empty value for tombstones","handlingStrategy":"try-catch","validationCode":"// before reading/partition processing\nif (cell.isTombstone() && cell.valueSize() > 0) {\n    log.warn(\"Skipping tombstone with value on column \" + column.name);\n    return;\n}","typeGuard":"boolean isWellFormedTombstone(Cell<?> c) { return c.isTombstone() && c.valueSize() == 0; }","tryCatchPattern":"try { metadata.validateCell(cell); } catch (MarshalException e) { log.error(\"Invalid cell: {}\", e.getMessage()); /* quarantine partition, run scrub/repair */ }","preventionTips":["Never construct tombstone cells with a non-empty value via internal APIs","Run nodetool scrub/verify periodically to catch corrupt SSTables early","Keep cluster nodes on compatible versions during rolling upgrades","Verify checksums and disk health after unclean shutdowns before replaying data"],"tags":["cassandra","storage","data-corruption"],"backgroundTag":"internal-invariant-violation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}