{"record":{"id":"3bf27f958c08444a","repo":"apache/cassandra","slug":"dropping-data-attempted-to-write-a-non-empty-v","errorCode":null,"errorMessage":"Dropping data... (Attempted to write a non-empty value using EmptyType)","messagePattern":"Dropping data\\.\\.\\. \\(Attempted to write a non-empty value using EmptyType\\)","errorType":"console","errorClass":"NonEmptyWriteException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/EmptyType.java","lineNumber":172,"sourceCode":"    public ByteBuffer readBuffer(DataInputPlus in, int maxValueSize)\n    {\n        return ByteBufferUtil.EMPTY_BYTE_BUFFER;\n    }\n\n    @Override\n    public void writeValue(ByteBuffer value, DataOutputPlus out)\n    {\n        if (!value.hasRemaining())\n            return;\n        // In 3.0 writeValue was added which required EmptyType to write data, and relied on caller to never do that;\n        // that behavior was unsafe so guard against it.  There are configurable behaviors, but the only allowed cases\n        // should be *_DATA_LOSS (last resort... really should avoid this) and fail; fail should be preferred in nearly\n        // all cases.\n        // see CASSANDRA-15790\n        switch (NON_EMPTY_WRITE_BEHAVIOR)\n        {\n            case LOG_DATA_LOSS:\n                NON_EMPTY_WRITE_LOGGER.warn(\"Dropping data...\", new NonEmptyWriteException(\"Attempted to write a non-empty value using EmptyType\"));\n            case SILENT_DATA_LOSS:\n                return;\n            case FAIL:\n            default:\n                throw new AssertionError(\"Attempted to write a non-empty value using EmptyType\");\n        }\n    }\n\n    private static final class NonEmptyWriteException extends RuntimeException\n    {\n        NonEmptyWriteException(String message)\n        {\n            super(message);\n        }\n    }\n\n    @Override\n    public ByteBuffer getMaskedValue()","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/EmptyType.java#L154-L190","documentation":"EmptyType columns must always serialize as zero bytes. When a non-empty value is written, writeValue consults the serialization.empty_type_nonempty_writes policy: FAIL (default) throws AssertionError, LOG_DATA_LOSS logs 'Dropping data...' with a NonEmptyWriteException stack and drops, SILENT_DATA_LOSS silently drops. This protects against silent data loss from schema mistakes (CASSANDRA-15790).","triggerScenarios":"INSERT/UPDATE with a non-empty value (e.g. a string or int) into a column of type empty, or a driver/application serializing a value into an empty-typed column, with the behavior property set to LOG_DATA_LOSS.","commonSituations":"Applications writing real values to a column intended as an 'exists-only' placeholder; schema migration accidentally changed a column to empty type; misuse of empty columns intended for existence checks.","solutions":["Fix the application/driver to write only empty (zero-length) values for empty-typed columns","If the column should hold data, ALTER the schema to a real type and migrate data","Leave the default property (FAIL) so such writes fail loudly instead of dropping data","If LOG_DATA_LOSS was intentionally set, audit logs for NonEmptyWriteException to find offending writes"],"exampleFix":"// before: inserting a value into an empty column\nINSERT INTO t (k, flag) VALUES (1, 'yes');\n// after: empty columns accept only empty values\nINSERT INTO t (k, flag) VALUES (1, '');","handlingStrategy":"try-catch","validationCode":"// client-side guard: only send empty values to empty-typed columns\nif (colType.equals(\"empty\") && value != null && value.length() > 0)\n    throw new IllegalArgumentException(\"Non-empty value for empty column: \" + colName);","typeGuard":null,"tryCatchPattern":"try { session.execute(insert); } catch (AssertionError | DriverException e) { logger.error(\"Write to empty-typed column rejected: {}\", e.getMessage()); }","preventionTips":["Keep the default FAIL behavior so bad writes surface immediately","Model existence-only columns deliberately and write only '' to them","Add application-side schema awareness for empty columns","Review schema after migrations that touch column types"],"tags":["serialization","data-loss","schema"],"backgroundTag":"database-write-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"}