{"record":{"id":"65bc9fc95cd381a9","repo":"prestodb/presto","slug":"node-selection-not-supported-65bc9f","errorCode":"NODE_SELECTION_NOT_SUPPORTED","errorMessage":"Unsupported node selection strategy for TTL scheduling: %s","messagePattern":"Unsupported node selection strategy for TTL scheduling: (.+?)","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/execution/scheduler/nodeSelection/SimpleTtlNodeSelector.java","lineNumber":194,"sourceCode":"        boolean isNodeSelectionStrategyNoPreference = splits.stream().allMatch(split -> split.getNodeSelectionStrategy() == NodeSelectionStrategy.NO_PREFERENCE);\n        // Current NodeSelectionStrategy support is limited to NO_PREFERENCE\n        if (!isNodeSelectionStrategyNoPreference) {\n            return simpleNodeSelector.computeAssignments(splits, existingTasks);\n        }\n\n        ImmutableMultimap.Builder<InternalNode, Split> assignment = ImmutableMultimap.builder();\n        NodeMap nodeMap = this.nodeMap.get().get();\n        NodeAssignmentStats assignmentStats = new NodeAssignmentStats(nodeTaskMap, nodeMap, existingTasks);\n\n        List<InternalNode> eligibleNodes = getEligibleNodes(maxTasksPerStage, nodeMap, existingTasks);\n        NodeSelection randomNodeSelection = new RandomNodeSelection(eligibleNodes, minCandidates);\n\n        boolean splitWaitingForAnyNode = false;\n\n        OptionalInt preferredNodeCount = OptionalInt.empty();\n        for (Split split : splits) {\n            if (split.getNodeSelectionStrategy() != NodeSelectionStrategy.NO_PREFERENCE) {\n                throw new PrestoException(\n                        NODE_SELECTION_NOT_SUPPORTED,\n                        format(\"Unsupported node selection strategy for TTL scheduling: %s\", split.getNodeSelectionStrategy()));\n            }\n\n            List<InternalNode> candidateNodes = randomNodeSelection.pickNodes(split);\n            if (candidateNodes.isEmpty()) {\n                Duration remainingTime = getEstimatedExecutionTimeRemaining();\n                if (fallbackToSimpleNodeSelection) {\n                    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());\n                    return simpleNodeSelector.computeAssignments(splits, existingTasks);\n                }\n\n                log.warn(\"No nodes available with enough TTL (%s) to schedule %s. Active nodes %s\", remainingTime, split, nodeMap.getActiveNodes());\n                throw new PrestoException(NO_NODES_AVAILABLE, \"No nodes available to run query\");\n            }\n\n            SplitWeight splitWeight = split.getSplitWeight();\n            Optional<InternalNodeInfo> chosenNodeInfo = simpleNodeSelector.chooseLeastBusyNode(","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/execution/scheduler/nodeSelection/SimpleTtlNodeSelector.java#L176-L212","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (etc/config.properties)\nnode-scheduler.use-ttl-scheduling=true\n// with hive bucketed execution -> NODE_SELECTION_NOT_SUPPORTED\n\n// after\nhive.bucketed-execution=false\n// or remove node-scheduler.use-ttl-scheduling=true","handlingStrategy":"validation","validationCode":"// Check strategy compatibility before enabling TTL scheduling\nboolean ttlCompatible = splits.stream()\n    .allMatch(s -> s.getNodeSelectionStrategy() == NodeSelectionStrategy.NO_PREFERENCE);\nif (useTtlScheduling && !ttlCompatible) {\n    // disable TTL scheduling for these splits or reject the workload\n}","typeGuard":"private static boolean supportsTtlScheduling(Split split) {\n    return split.getNodeSelectionStrategy() == NodeSelectionStrategy.NO_PREFERENCE;\n}","tryCatchPattern":"try {\n    return ttlNodeSelector.computeAssignments(splits, existingTasks);\n} catch (PrestoException e) {\n    if (e.getErrorCode().getName().equals(\"NODE_SELECTION_NOT_SUPPORTED\")) {\n        return simpleNodeSelector.computeAssignments(splits, existingTasks);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["scheduler","ttl","node-selection","configuration","presto"],"backgroundTag":"node-selection-not-supported","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}