{"record":{"id":"0135f86a104fd930","repo":"apache/cassandra","slug":"only-complex-cells-should-have-a-cell-path","errorCode":null,"errorMessage":"Only complex cells should have a cell path","messagePattern":"Only complex cells should have a cell path","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/schema/ColumnMetadata.java","lineNumber":683,"sourceCode":"        }\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)\n    {\n        if (!isComplex())\n            throw new MarshalException(\"Only complex cells should have a cell path\");\n\n        assert type.isMultiCell();\n        if (type.isCollection())\n            ((CollectionType)type).nameComparator().validate(path.get(0));\n        else\n            ((UserType)type).nameComparator().validate(path.get(0));\n    }\n\n    public void appendCqlTo(CqlBuilder builder)\n    {\n        builder.append(name)\n               .append(' ')\n               .append(type);\n\n        if (isStatic())\n            builder.append(\" static\");\n\n        if (isMasked())","sourceCodeStart":665,"sourceCodeEnd":701,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/schema/ColumnMetadata.java#L665-L701","documentation":"Cassandra throws this MarshalException when deserializing/validating a cell that carries a CellPath (the per-cell component used by collections, UDTs and other multi-cell/complex types) but the column itself is not complex (single-cell). Only complex columns can have path components, so a path on a simple column indicates corrupt or malformed data.","triggerScenarios":"ColumnMetadata.validateCell() calls validateCellPath() with a non-null CellPath while isComplex() is false — e.g. deserializing a partition containing a cell with a path for a frozen/single-cell column, or after altering a column from a non-frozen collection to frozen (making it single-cell) while old cells with paths still exist.","commonSituations":"Reading SSTables or receiving mutations written before an ALTER TYPE / frozen conversion; hand-crafted or corrupted commit log/mutation data; schema changes that changed a column's cell kind without rewriting existing data.","solutions":["Verify the column definition matches the data being read (a frozen column must not receive cells with paths); unfreeze/keep the column multi-cell if path-carrying data must be read.","Run nodetool scrub / repairs on the affected table to drop or rewrite corrupt cells.","If triggered by an ALTER, ensure the column was altered consistently on all nodes and migrate data with INSERT after the schema change instead of reading stale cells.","If you construct cells programmatically (internal tooling), only set a CellPath for isComplex() columns."],"exampleFix":"// before (writing a cell with a path for a frozen column)\nCell<Object> cell = BufferCell.live(column, ts, value, CellPath.create(b));\n// after\nCell<Object> cell = column.isComplex()\n    ? BufferCell.live(column, ts, value, CellPath.create(b))\n    : BufferCell.live(column, ts, value);","handlingStrategy":"validation","validationCode":"if (!column.isComplex() && cell.path() != null)\n    throw new IllegalArgumentException(\"Cell path set for non-complex column \" + column.name);","typeGuard":"boolean canHavePath(ColumnMetadata col) { return col.isComplex(); }","tryCatchPattern":"try { /* deserialize/validate */ } catch (MarshalException e) {\n    logger.error(\"Corrupt cell for {}: {}\", column.name, e.getMessage());\n    // trigger repair/scrub of the affected range\n}","preventionTips":["Only attach CellPath to multi-cell (non-frozen collection/UDT) columns.","After altering a column to frozen, rewrite data rather than reading stale cells.","Schedule scrub/repair after schema migrations that change cell kind."],"tags":["cassandra","deserialization","data-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}