apache/druid · error · DruidException

Method not supported. This method is not expected to be…

Error message

Method not supported. This method is not expected to be called!

What it means

UnionQuery represents a union of queries without a single scan duration; the Query interface's getDuration() is meaningless for it, so the implementation unconditionally throws methodNotSupported(). It is a defensive guard: any caller attempting to read a duration from a union query is using the API incorrectly.

Solutions

  1. Check instanceof UnionQuery (or use a visitor) before calling getDuration()
  2. Treat union queries via their constituent queries to obtain durations
  3. Avoid placing UnionQuery in structures whose equals/hashCode path invokes getDuration()

Example fix

// before
Duration d = query.getDuration();
// after
final Duration d = query instanceof UnionQuery ? null : query.getDuration();
Defensive patterns

Strategy: type-guard

Validate before calling

if (query instanceof UnionQuery) {
  throw new IllegalStateException("UnionQuery has no duration");
}

Type guard

static boolean hasDuration(Query<?> q) {
  return !(q instanceof UnionQuery);
}

Try / catch

try {
  Duration d = query.getDuration();
} catch (UnsupportedOperationException e) {
  // union query: handle sub-queries instead
}

Prevention

When it happens

Trigger: Calling getDuration() on a Query object that is actually a UnionQuery — e.g. generic code that inspects any Query's duration, or equals/hashCode paths in collections that touch duration-deriving state.

Common situations: Tooling or custom code iterating over Query trees and calling Query interface methods uniformly; debugging/serializing union queries; third-party code assuming all queries are scan/base queries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/e7ebbe89e6596dfb. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/union/UnionQuery.java:123

    return getClass().getSimpleName();
  }

  @Override
  public QueryRunner<Object> getRunner(QuerySegmentWalker walker)
  {
    throw DruidException.defensive("Use QueryToolChest to get a Runner");
  }

  @Override
  public List<Interval> getIntervals()
  {
    return Collections.emptyList();
  }

  @Override
  public Duration getDuration()
  {
    throw methodNotSupported();
  }

  @Override
  public Granularity getGranularity()
  {
    return Granularities.ALL;
  }

  @Override
  public DateTimeZone getTimezone()
  {
    throw methodNotSupported();
  }

  @Override
  public Map<String, Object> getContext()
  {
    return context;

View on GitHub (pinned to 9b90983fd2)