{"record":{"id":"0de72c876079f8ef","repo":"apache/cassandra","slug":"write-to-s-s-partition-s-s-writewarningssnap-0de72c","errorCode":null,"errorMessage":"Write to %s.%s partition %s: %s (WriteWarningsSnapshot.writeTombstoneWarnMessage(value))","messagePattern":"Write to (.+?)\\.(.+?) partition (.+?): (.+?) \\(WriteWarningsSnapshot\\.writeTombstoneWarnMessage\\(value\\)\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/service/writes/thresholds/CoordinatorWriteWarnings.java","lineNumber":161,"sourceCode":"\n        for (Map.Entry<TableId, Long> entry : snapshot.writeTombstone.tableValues.entrySet())\n        {\n            TableId tableId = entry.getKey();\n            ColumnFamilyStore cfs = Schema.instance.getColumnFamilyStoreInstance(tableId);\n            if (cfs == null)\n            {\n                logger.warn(\"ColumnFamilyStore is null for table {}, skipping\", tableId);\n                continue;\n            }\n\n            TableMetadata metadata = cfs.metadata();\n            String partitionKey = metadata.partitionKeyType.toCQLString(warnings.partitionKey.getKey());\n            String msg = String.format(\"Write to %s.%s partition %s: %s\",\n                                       metadata.keyspace,\n                                       metadata.name,\n                                       partitionKey,\n                                       WriteWarningsSnapshot.writeTombstoneWarnMessage(entry.getValue()));\n            ClientWarn.instance.warn(msg);\n            logger.warn(msg);\n            cfs.metric.writeTombstoneWarnings.mark();\n        }\n    }\n\n    /**\n     * Internal state holder for accumulated warnings.\n     * A Mutation is always for a single partition key, so we store it once\n     * and track warnings per table within that partition.\n     */\n    private static class Warnings\n    {\n        @Nullable\n        DecoratedKey partitionKey;\n\n        @Nullable\n        WriteWarningsSnapshot snapshot;\n","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/writes/thresholds/CoordinatorWriteWarnings.java#L143-L179","documentation":"CoordinatorWriteWarnings.processWarnings() reports per-table tombstone-write warnings. When mutations to a partition produced tombstones whose value exceeded the write-tombstone warning threshold, the coordinator emits 'Write to <ks>.<table> partition <key>: <detail>' as a client warning, logs it, and marks writeTombstoneWarnings. It signals expensive tombstone-generating writes.","triggerScenarios":"Writes (deletes, TTL expirations materialized, null/overwrites) generating tombstones above the write tombstone warn threshold on replicas, aggregated into WriteWarningsSnapshot and processed by the coordinator.","commonSituations":"Application deleting many rows/cells in one partition; overwriting columns with nulls (which create tombstones); high-churn workloads with frequent deletes.","solutions":["Stop using null-overwrites to delete; use explicit DELETEs and avoid patterns that generate tombstones","Use TTLs and ensure compaction keeps pace; consider TimeWindowCompactionStrategy for TTL-heavy tables","Raise the write tombstone warn threshold in cassandra.yaml if the tombstone volume is by design","Locate the offending partition from the warning and adjust the client's write pattern"],"exampleFix":"// before: creates a tombstone per overwrite\nUPDATE t SET col = null WHERE k = 1;\n// after\ndelete col from t where k = 1; -- or drop the column usage entirely","handlingStrategy":"validation","validationCode":"// avoid tombstone-generating writes at the app layer\nif (isSettingColumnsToNull(statement))\n    throw new IllegalArgumentException(\"Use DELETE instead of null-overwrite: \" + cql);","typeGuard":null,"tryCatchPattern":"ResultSet rs = session.execute(write);\nfor (String w : rs.getExecutionInfo().getWarnings())\n    if (w.startsWith(\"Write to \") && w.contains(\"tombstone\"))\n        tombstoneAuditor.record(w);","preventionTips":["Never overwrite with nulls to delete values","Prefer TTL over explicit deletes for expiring data","Ensure compaction keeps pace with delete churn"],"tags":["write","warnings","tombstones","coordinator"],"backgroundTag":"payload-too-large","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"}