{"record":{"id":"a962a13d088c5c67","repo":"apache/cassandra","slug":"warnings-msg-with-loggabletokens-client-warni","errorCode":null,"errorMessage":"<warnings msg> with <loggableTokens> (client warning; msg from WarningsSnapshot abort message e.g. tombstoneAbortMessage(count, maxValue, cql))","messagePattern":"<warnings msg> with <loggableTokens> \\(client warning; msg from WarningsSnapshot abort message e\\.g\\. tombstoneAbortMessage\\(count, maxValue, cql\\)\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/reads/thresholds/CoordinatorWarnings.java","lineNumber":130,"sourceCode":"\n            recordAborts(merged.indexReadSSTablesCount, cql, loggableTokens, cfs.metric.tooManySSTableIndexesReadAborts, WarningsSnapshot::tooManyIndexesReadAbortMessage);\n            recordWarnings(merged.indexReadSSTablesCount, cql, loggableTokens, cfs.metric.tooManySSTableIndexesReadWarnings, WarningsSnapshot::tooManyIndexesReadWarnMessage);\n        });\n    }\n\n    // utility interface to let callers use static functions\n    @FunctionalInterface\n    private interface ToString\n    {\n        String apply(int count, long value, String cql);\n    }\n\n    private static void recordAborts(WarningsSnapshot.Warnings counter, String cql, String loggableTokens, TableMetrics.TableMeter metric, ToString toString)\n    {\n        if (!counter.aborts.instances.isEmpty())\n        {\n            String msg = toString.apply(counter.aborts.instances.size(), counter.aborts.maxValue, cql);\n            ClientWarn.instance.warn(msg + \" with \" + loggableTokens);\n            logger.warn(msg);\n            metric.mark();\n        }\n    }\n\n    private static void recordWarnings(WarningsSnapshot.Warnings counter, String cql, String loggableTokens, TableMetrics.TableMeter metric, ToString toString)\n    {\n        if (!counter.warnings.instances.isEmpty())\n        {\n            String msg = toString.apply(counter.warnings.instances.size(), counter.warnings.maxValue, cql);\n            ClientWarn.instance.warn(msg + \" with \" + loggableTokens);\n            logger.warn(msg);\n            metric.mark();\n        }\n    }\n\n    /**\n     * Utility class to create an immutable map which does not fail on mutation but instead ignores it.","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/reads/thresholds/CoordinatorWarnings.java#L112-L148","documentation":"CoordinatorWarnings.recordAborts() reports read-threshold ABORTS accumulated in a WarningsSnapshot (e.g. tombstone aborts). When a node reports abort instances, the coordinator sends '<abort msg> with <loggableTokens>' as a client warning, logs the message, and marks the corresponding table metric. Unlike warnings, aborts mean part of the read result was rejected.","triggerScenarios":"A query's read (typically replica-side tombstone/logged-row scans) crossed an abort threshold (e.g. tombstone_abort threshold) on replicas; on the next processWarnings cycle the snapshot contains abort instances and this path emits the client warning.","commonSituations":"Queries over tables with heavy tombstone accumulation; deletes/expiry (TTL) creating many tombstones; compaction falling behind so reads traverse many dead cells.","solutions":["Rewrite the query to hit fewer partitions/sstables (add partition key constraints)","Run compaction / gc_grace tuning to clear accumulated tombstones, and investigate why tombstones pile up","Adjust the relevant abort threshold (e.g. tombstone_abort thresholds in cassandra.yaml) only with understanding of the read-cost tradeoff","Check the log line for the full abort message (count, max value, CQL) to identify the offending query/table"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// before running the query, estimate tombstones scanned\nlong est = tombstoneEstimateFor(table, whereClause);\nif (est > abortThreshold) throw new IllegalArgumentException(\"Query would abort: \" + cql);","typeGuard":null,"tryCatchPattern":"try (ResultSet rs = session.execute(cql)) {\n    rs.getExecutionInfo().getWarnings().stream()\n      .filter(w -> w.contains(\"abort\"))\n      .forEach(w -> alertOps(\"read aborted: \" + w));\n}","preventionTips":["Keep tombstone counts low; run regular compaction","Add partition-key constraints to narrow reads","Monitor tombstone-abort table metrics"],"tags":["warnings","tombstones","query","coordinator"],"backgroundTag":"value-out-of-range","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"}