apache/cassandra · error

<warnings msg> with <loggableTokens> (client warning; msg fr

Error message

<warnings msg> with <loggableTokens> (client warning; msg from WarningsSnapshot abort message e.g. tombstoneAbortMessage(count, maxValue, cql))

What it means

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.

Source

Thrown at src/java/org/apache/cassandra/service/reads/thresholds/CoordinatorWarnings.java:130

            recordAborts(merged.indexReadSSTablesCount, cql, loggableTokens, cfs.metric.tooManySSTableIndexesReadAborts, WarningsSnapshot::tooManyIndexesReadAbortMessage);
            recordWarnings(merged.indexReadSSTablesCount, cql, loggableTokens, cfs.metric.tooManySSTableIndexesReadWarnings, WarningsSnapshot::tooManyIndexesReadWarnMessage);
        });
    }

    // utility interface to let callers use static functions
    @FunctionalInterface
    private interface ToString
    {
        String apply(int count, long value, String cql);
    }

    private static void recordAborts(WarningsSnapshot.Warnings counter, String cql, String loggableTokens, TableMetrics.TableMeter metric, ToString toString)
    {
        if (!counter.aborts.instances.isEmpty())
        {
            String msg = toString.apply(counter.aborts.instances.size(), counter.aborts.maxValue, cql);
            ClientWarn.instance.warn(msg + " with " + loggableTokens);
            logger.warn(msg);
            metric.mark();
        }
    }

    private static void recordWarnings(WarningsSnapshot.Warnings counter, String cql, String loggableTokens, TableMetrics.TableMeter metric, ToString toString)
    {
        if (!counter.warnings.instances.isEmpty())
        {
            String msg = toString.apply(counter.warnings.instances.size(), counter.warnings.maxValue, cql);
            ClientWarn.instance.warn(msg + " with " + loggableTokens);
            logger.warn(msg);
            metric.mark();
        }
    }

    /**
     * Utility class to create an immutable map which does not fail on mutation but instead ignores it.

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Rewrite the query to hit fewer partitions/sstables (add partition key constraints)
  2. Run compaction / gc_grace tuning to clear accumulated tombstones, and investigate why tombstones pile up
  3. Adjust the relevant abort threshold (e.g. tombstone_abort thresholds in cassandra.yaml) only with understanding of the read-cost tradeoff
  4. Check the log line for the full abort message (count, max value, CQL) to identify the offending query/table
Defensive patterns

Strategy: try-catch

Validate before calling

// before running the query, estimate tombstones scanned
long est = tombstoneEstimateFor(table, whereClause);
if (est > abortThreshold) throw new IllegalArgumentException("Query would abort: " + cql);

Try / catch

try (ResultSet rs = session.execute(cql)) {
    rs.getExecutionInfo().getWarnings().stream()
      .filter(w -> w.contains("abort"))
      .forEach(w -> alertOps("read aborted: " + w));
}

Prevention

When it happens

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

Common situations: Queries over tables with heavy tombstone accumulation; deletes/expiry (TTL) creating many tombstones; compaction falling behind so reads traverse many dead cells.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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