apache/cassandra · warning
Top-K queries can only be run with consistency level ONE /…
Error message
Top-K queries can only be run with consistency level ONE / LOCAL_ONE / NODE_LOCAL. Consistency level %s was requested. Downgrading the consistency level to %s.
What it means
Top-K (vector ANN) queries only support consistency levels ONE / LOCAL_ONE / NODE_LOCAL. When a higher consistency level is requested, SelectStatement.execute silently downgrades it to LOCAL_ONE (if the requested level was datacenter-local) or ONE and warns the client.
Solutions
- Set consistency level ONE or LOCAL_ONE explicitly on ANN queries (e.g. driver withDefaultConsistencyLevel or per-query setConsistencyLevel)
- Use LOCAL_ONE for cross-DC deployments to keep reads local
- Separate ANN queries into a dedicated session/profile with the correct consistency profile
Example fix
// before
SimpleStatement q = SimpleStatement.builder("SELECT ... ORDER BY embedding ANN OF [0.1,0.2] LIMIT 5").build(); // default QUORUM
// after
SimpleStatement q = SimpleStatement.builder("SELECT ... ORDER BY embedding ANN OF [0.1,0.2] LIMIT 5")
.setConsistencyLevel(ConsistencyLevel.LOCAL_ONE).build(); Defensive patterns
Strategy: validation
Validate before calling
if (isAnnQuery && cl != ConsistencyLevel.ONE && cl != ConsistencyLevel.LOCAL_ONE) {
throw new IllegalArgumentException("ANN query requires ONE/LOCAL_ONE, got " + cl);
} Prevention
- Dedicated driver execution profile for vector queries with LOCAL_ONE
- Never rely on global default consistency for ANN queries
- Log client warnings (driver setWarningHandler) to catch silent downgrades
When it happens
Trigger: Executing an ANN/Top-K SELECT (ORDER BY ... ANN OF vector) with consistency level QUORUM, LOCAL_QUORUM, THREE, EACH_QUORUM, ALL, etc.; the coordinator rewrites QueryOptions and warns via ClientWarn.
Common situations: Application sets a driver default consistency level of QUORUM/LOCAL_QUORUM and issues vector searches; code shared between normal reads and ANN reads; porting queries from non-vector workloads.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Top-K queries do not support paging and the page size is…
- Aggregation query used on multiple partition keys (IN…
- Aggregation query used without partition key
- All arguments must have the same vector dimensions
- ANN ordering does not support any other ordering
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ff548902a7ae1381.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/SelectStatement.java:405
// Handle additional validation for topK queries
if (restrictions.isTopK())
{
checkFalse(aggregationSpec != null, TOPK_AGGREGATION_ERROR);
// We aren't going to allow SERIAL at all, so we can error out on those.
checkFalse(options.getConsistency() == ConsistencyLevel.LOCAL_SERIAL ||
options.getConsistency() == ConsistencyLevel.SERIAL,
String.format(TOPK_CONSISTENCY_LEVEL_ERROR, options.getConsistency()));
if (options.getConsistency().needsReconciliation())
{
ConsistencyLevel supplied = options.getConsistency();
ConsistencyLevel downgrade = supplied.isDatacenterLocal() ? ConsistencyLevel.LOCAL_ONE : ConsistencyLevel.ONE;
options = QueryOptions.withConsistencyLevel(options, downgrade);
ClientWarn.instance.warn(String.format(TOPK_CONSISTENCY_LEVEL_WARNING, supplied, downgrade));
}
checkFalse(limit.isUnlimited(), TOPK_LIMIT_ERROR);
checkFalse(limit.perPartitionCount() != DataLimits.NO_LIMIT, TOPK_PARTITION_LIMIT_ERROR);
if (pageSize > 0 && pageSize < limit.count())
{
int oldPageSize = pageSize;
pageSize = limit.count();
limit = getDataLimits(userLimit, userPerPartitionLimit, pageSize, aggregationSpec);
options = QueryOptions.withPageSize(options, pageSize);
ClientWarn.instance.warn(String.format(TOPK_PAGE_SIZE_WARNING, oldPageSize, limit.count(), pageSize));
}
}
ReadQuery query = getQuery(options, state.getClientState(), selectors.getColumnFilter(), nowInSec, limit, PotentialTxnConflicts.DISALLOW);
View on GitHub (pinned to 88fd0f6a0e)