apache/druid · error · UnsupportedOperationException

Invalid operation for AveragerFactoryWrapper.

Error message

Invalid operation for AveragerFactoryWrapper.

What it means

AveragerFactoryWrapper.factorize is deliberately unimplemented: this wrapper adapts an AveragerFactory for the moving-average query engine and must never produce a standard (non-windowed) Aggregator. The moving-average machinery uses getAveragerFactory/averagers instead of Druid's normal factorize path, so any call here means the factory leaked into the standard aggregation pipeline.

Source

Thrown at extensions-contrib/moving-average-query/src/main/java/org/apache/druid/query/movingaverage/AveragerFactoryWrapper.java:69

  /**
   * Simple constructor
   *
   * @param af
   * @param prefix
   */
  public AveragerFactoryWrapper(AveragerFactory<T, R> af, String prefix)
  {
    this.af = af;
    this.prefix = prefix;
  }

  /**
   * Not implemented. Throws UnsupportedOperationException.
   */
  @Override
  public Aggregator factorize(ColumnSelectorFactory metricFactory) throws UnsupportedOperationException
  {
    throw new UnsupportedOperationException("Invalid operation for AveragerFactoryWrapper.");
  }

  /**
   * Not implemented. Throws UnsupportedOperationException.
   */
  @Override
  public BufferAggregator factorizeBuffered(ColumnSelectorFactory metricFactory)
  {
    throw new UnsupportedOperationException("Invalid operation for AveragerFactoryWrapper.");
  }

  /* (non-Javadoc)
   * @see org.apache.druid.query.aggregation.AggregatorFactory#getComparator()
   */
  @Override
  public Comparator<?> getComparator()
  {
    return af.getComparator();

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Only use 'averager' specs inside the 'aggregations' of a movingAverage query, not in groupBy/topN/timesSeries aggregations
  2. If a standard aggregation is needed, replace the averager with a native Druid aggregator (e.g. doubleSum) plus post-aggregators
  3. Verify the query type is 'movingAverage' and the averager specs sit under its aggregations field

Example fix

// before
{"queryType":"groupBy", "aggregations":[{"type":"averager", ...}]}
// after
{"queryType":"movingAverage", "aggregations":[{"type":"averager", ...}]}
Defensive patterns

Strategy: validation

Validate before calling

// Validate query JSON before submission
function assertAveragerOnlyInMovingAverage(query) {
  if (query.queryType !== 'movingAverage' &&
      (query.aggregations || []).some(a => a.type === 'averager')) {
    throw new Error('averager specs are only valid in movingAverage queries');
  }
}

Try / catch

try { runQuery(q); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("AveragerFactoryWrapper")) { /* switch to movingAverage query type */ } else { throw e; } }

Prevention

When it happens

Trigger: An 'averager' aggregator spec from a movingAverage query is used outside the moving-average engine, e.g. placed in a regular groupBy/topN aggregations list, causing Druid to call factorize on it.

Common situations: Config mistake: putting moving-average averager specs into a normal query's aggregations; reusing movingAverage query JSON in a groupBy; a query engine path that ignores movingAverage-specific handling.

Related errors


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