prestodb/presto · error · PrestoException
NODE_SELECTION_NOT_SUPPORTED
NODE_SELECTION_NOT_SUPPORTED
Error message
Unsupported node selection strategy for TTL scheduling: %s
What it means
SimpleTtlNodeSelector only supports splits using the NO_PREFERENCE node selection strategy. When TTL-based scheduling is enabled and a split arrives with HARD_AFFINITY or SOFT_AFFINITY, the selector throws NODE_SELECTION_NOT_SUPPORTED because TTL-aware placement cannot honor node affinity preferences. The entry point first checks whether all splits are NO_PREFERENCE and otherwise delegates to simpleNodeSelector; this throw is a defensive per-split check inside the loop.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/scheduler/nodeSelection/SimpleTtlNodeSelector.java:194
boolean isNodeSelectionStrategyNoPreference = splits.stream().allMatch(split -> split.getNodeSelectionStrategy() == NodeSelectionStrategy.NO_PREFERENCE);
// Current NodeSelectionStrategy support is limited to NO_PREFERENCE
if (!isNodeSelectionStrategyNoPreference) {
return simpleNodeSelector.computeAssignments(splits, existingTasks);
}
ImmutableMultimap.Builder<InternalNode, Split> assignment = ImmutableMultimap.builder();
NodeMap nodeMap = this.nodeMap.get().get();
NodeAssignmentStats assignmentStats = new NodeAssignmentStats(nodeTaskMap, nodeMap, existingTasks);
List<InternalNode> eligibleNodes = getEligibleNodes(maxTasksPerStage, nodeMap, existingTasks);
NodeSelection randomNodeSelection = new RandomNodeSelection(eligibleNodes, minCandidates);
boolean splitWaitingForAnyNode = false;
OptionalInt preferredNodeCount = OptionalInt.empty();
for (Split split : splits) {
if (split.getNodeSelectionStrategy() != NodeSelectionStrategy.NO_PREFERENCE) {
throw new PrestoException(
NODE_SELECTION_NOT_SUPPORTED,
format("Unsupported node selection strategy for TTL scheduling: %s", split.getNodeSelectionStrategy()));
}
List<InternalNode> candidateNodes = randomNodeSelection.pickNodes(split);
if (candidateNodes.isEmpty()) {
Duration remainingTime = getEstimatedExecutionTimeRemaining();
if (fallbackToSimpleNodeSelection) {
log.warn("No nodes available with enough TTL (%s) to schedule %s. Active nodes %s, falling back to simple node selection.", remainingTime, split, nodeMap.getActiveNodes());
return simpleNodeSelector.computeAssignments(splits, existingTasks);
}
log.warn("No nodes available with enough TTL (%s) to schedule %s. Active nodes %s", remainingTime, split, nodeMap.getActiveNodes());
throw new PrestoException(NO_NODES_AVAILABLE, "No nodes available to run query");
}
SplitWeight splitWeight = split.getSplitWeight();
Optional<InternalNodeInfo> chosenNodeInfo = simpleNodeSelector.chooseLeastBusyNode(View on GitHub (pinned to 55bb57d202)
Solutions
- Disable TTL-based scheduling (remove node-scheduler.use-ttl-scheduling=true and related TTL config) so SimpleNodeSelector handles affinity splits.
- Identify which connector/stage produces non-NO_PREFERENCE splits from the strategy value in the message and disable bucketed/affinity execution for it (e.g. hive.bucketed-execution=false).
- Upgrade Presto: newer versions fall back to simpleNodeSelector for unsupported strategies instead of throwing.
- Isolate TTL-scheduled workloads on a separate catalog/cluster from affinity-based workloads.
Example fix
// before (etc/config.properties) node-scheduler.use-ttl-scheduling=true // with hive bucketed execution -> NODE_SELECTION_NOT_SUPPORTED // after hive.bucketed-execution=false // or remove node-scheduler.use-ttl-scheduling=true
Defensive patterns
Strategy: validation
Validate before calling
// Check strategy compatibility before enabling TTL scheduling
boolean ttlCompatible = splits.stream()
.allMatch(s -> s.getNodeSelectionStrategy() == NodeSelectionStrategy.NO_PREFERENCE);
if (useTtlScheduling && !ttlCompatible) {
// disable TTL scheduling for these splits or reject the workload
} Type guard
private static boolean supportsTtlScheduling(Split split) {
return split.getNodeSelectionStrategy() == NodeSelectionStrategy.NO_PREFERENCE;
} Try / catch
try {
return ttlNodeSelector.computeAssignments(splits, existingTasks);
} catch (PrestoException e) {
if (e.getErrorCode().getName().equals("NODE_SELECTION_NOT_SUPPORTED")) {
return simpleNodeSelector.computeAssignments(splits, existingTasks);
}
throw e;
} Prevention
- Do not enable TTL scheduling on clusters that run bucketed/affinity-based (HARD_AFFINITY) workloads.
- Pin connector settings like hive.bucketed-execution=false when TTL scheduling is on.
- Upgrade Presto - newer builds delegate unsupported strategies to SimpleNodeSelector instead of throwing.
- Test new connectors against TTL-enabled clusters in staging before production rollout.
When it happens
Trigger: TTL-based scheduling enabled (node-scheduler.use-ttl-scheduling / TTL match scheduler config) while query splits use HARD_AFFINITY or SOFT_AFFINITY (e.g. bucketed execution, connector node preferences) and the top-level allMatch(NO_PREFERENCE) guard does not catch the mix.
Common situations: Enabling TTL scheduling on a cluster running bucketed Hive joins (bucketed execution forces HARD_AFFINITY); mixed workloads where some stages produce affinity splits while TTL scheduling is globally on; connector upgrades that start emitting preferred nodes while TTL scheduling is enabled.
Related errors
- NO_NODES_AVAILABLE
- Unknown cluster Ttl provider manager
- Unknown Node Ttl Fetcher Manager:
- ACCUMULO_TABLE_EXISTS
- NOT_SUPPORTED
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/65bc9fc95cd381a9.
Report an issue: GitHub.