{"record":{"id":"bab1d9c2b444bc16","repo":"apache/druid","slug":"cannot-query-datasource-locally-s","errorCode":null,"errorMessage":"Cannot query dataSource locally: %s","messagePattern":"Cannot query dataSource locally: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/server/LocalQuerySegmentWalker.java","lineNumber":91,"sourceCode":"      PolicyEnforcer policyEnforcer,\n      ServiceEmitter emitter\n  )\n  {\n    this.conglomerate = conglomerate;\n    this.segmentWrangler = segmentWrangler;\n    this.joinableFactoryWrapper = joinableFactoryWrapper;\n    this.scheduler = scheduler;\n    this.policyEnforcer = policyEnforcer;\n    this.emitter = emitter;\n  }\n\n  @Override\n  public <T> QueryRunner<T> getQueryRunnerForIntervals(final Query<T> query, final Iterable<Interval> intervals)\n  {\n    ExecutionVertex ev = ExecutionVertex.of(query);\n\n    if (!ev.canRunQueryUsingLocalWalker()) {\n      throw new IAE(\"Cannot query dataSource locally: %s\", ev.getBaseDataSource());\n    }\n\n    // wrap in ReferenceCountingSegment, these aren't currently managed by SegmentManager so reference tracking doesn't\n    // matter, but at least some or all will be in a future PR\n    final Iterable<Optional<Segment>> segments =\n        FunctionalIterable.create(segmentWrangler.getSegmentsForIntervals(ev.getBaseDataSource(), intervals))\n                          .transform(ReferenceCountedSegmentProvider::unmanaged);\n\n    final AtomicLong cpuAccumulator = new AtomicLong(0L);\n\n    final SegmentMapFunction segmentMapFn = ev.createSegmentMapFunction(policyEnforcer);\n\n    final QueryRunnerFactory<T, Query<T>> queryRunnerFactory = conglomerate.findFactory(query);\n    final QueryRunner<T> baseRunner = queryRunnerFactory.mergeRunners(\n        DirectQueryProcessingPool.INSTANCE,\n        () -> StreamSupport.stream(segments.spliterator(), false)\n                           .map(s -> segmentMapFn.apply(s).orElseThrow())\n                           .map(queryRunnerFactory::createRunner).iterator()","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/server/LocalQuerySegmentWalker.java#L73-L109","documentation":"LocalQuerySegmentWalker can only execute queries whose dataSource is locally runnable (e.g. table/lookup sources). If the query's DataSource cannot run on the local walker (like a query dataSource or join type the local walker does not support), it throws IAE naming the dataSource.","triggerScenarios":"Issuing a native query with a QueryDataSource/union/unsupported join directly against a broker configured to use the local segment walker; querying a dataSource type (e.g. inline in some configs) not supported by the wrangler.","commonSituations":"Submitting nested native queries to a node that only has the local walker (no distributed broker); tests or embedded cluster setups running queries whose dataSource requires MSQ or a router.","solutions":["Run the query on the broker/router with the distributed walker instead of the local one","Rewrite the query so its dataSource is a plain table source (flatten the subquery or run subqueries separately)","Check ExecutionVertex.canRunQueryUsingLocalWalker semantics and adapt the query shape","Enable/extend wrangler support for the dataSource type if running in an embedded/test cluster"],"exampleFix":"// before\nquery with dataSource = new QueryDataSource(nestedGroupBy)\nsubmitted directly to local walker\n// after\nrun nestedGroupBy first, then use its results as a table/inline dataSource:\nQuery<?> inner = ...; // execute separately\nTableDataSource outer = new TableDataSource(\"myTable\");","handlingStrategy":"try-catch","validationCode":"ExecutionVertex ev = ExecutionVertex.of(query);\nif (!ev.canRunQueryUsingLocalWalker()) {\n  throw new IllegalArgumentException(\"dataSource not locally runnable: \" + ev.getBaseDataSource());\n}","typeGuard":"boolean locallyRunnable(Query<?> q) {\n  return ExecutionVertex.of(q).canRunQueryUsingLocalWalker();\n}","tryCatchPattern":"try {\n  return walker.getQueryRunnerForIntervals(query, intervals);\n} catch (IAE e) {\n  if (e.getMessage().startsWith(\"Cannot query dataSource locally\")) {\n    log.warn(\"Re-routing query to distributed broker: %s\", e.getMessage());\n    return distributedBroker.getQueryRunnerForIntervals(query, intervals);\n  }\n  throw e;\n}","preventionTips":["Only submit plain table-source queries to nodes using the local walker","Route nested/complex native queries through the broker","Check ExecutionVertex.canRunQueryUsingLocalWalker before execution in embedded setups","Avoid custom dataSource types unless the walker supports them"],"tags":["query","native-query","datasource","unsupported"],"backgroundTag":"unsupported-operation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}