apache/cassandra · error · MarshalException

A tombstone should not have a value

Error message

A tombstone should not have a value

What it means

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.

Solutions

  1. Run nodetool scrub on the affected table to drop corrupt cells
  2. Restore the affected SSTables/backups or run repair to obtain clean copies from healthy replicas
  3. Check cluster version consistency and client write paths that build Cells directly; re-produce with a repro test if writing via internal APIs

Example fix

// before (internal API misuse)
Cell<v> bad = BufferCell.live(column, ts, value, del("2024-01-01T00:00:00Z"));
// after
Cell<v> ok = BufferCell.tombstone(column.deletionTime(), ts, path); // empty value for tombstones
Defensive patterns

Strategy: try-catch

Validate before calling

// before reading/partition processing
if (cell.isTombstone() && cell.valueSize() > 0) {
    log.warn("Skipping tombstone with value on column " + column.name);
    return;
}

Type guard

boolean isWellFormedTombstone(Cell<?> c) { return c.isTombstone() && c.valueSize() == 0; }

Try / catch

try { metadata.validateCell(cell); } catch (MarshalException e) { log.error("Invalid cell: {}", e.getMessage()); /* quarantine partition, run scrub/repair */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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


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

Appendix: source

Thrown at src/java/org/apache/cassandra/schema/ColumnMetadata.java:662

    }

    public boolean isSimple()
    {
        return !isComplex();
    }

    public CellPath.Serializer cellPathSerializer()
    {
        // Collections are our only complex so far, so keep it simple
        return CollectionType.cellPathSerializer;
    }

    public <V> void validateCell(Cell<V> cell)
    {
        if (cell.isTombstone())
        {
            if (cell.valueSize() > 0)
                throw new MarshalException("A tombstone should not have a value");
            if (cell.path() != null)
                validateCellPath(cell.path());
        }
        else if(type.isUDT())
        {
            // To validate a non-frozen UDT field, both the path and the value
            // are needed, the path being an index into an array of value types.
            ((UserType)type).validateCell(cell);
        }
        else
        {
            type.validateCellValue(cell.value(), cell.accessor());
            if (cell.path() != null)
                validateCellPath(cell.path());
        }
    }

    private void validateCellPath(CellPath path)

View on GitHub (pinned to 88fd0f6a0e)