apache/druid · error · UnsupportedOperationException

DoubleAnyAggregatorFactory is not supported during ingestion

Error message

DoubleAnyAggregatorFactory is not supported during ingestion for rollup

What it means

DoubleAnyAggregatorFactory cannot be used for rollup at ingestion time: the 'any' aggregator keeps only the last-seen value and has no deterministic combiner that Druid's rollup machinery (AggregateCombiner) can use to merge across cursors. makeAggregateCombiner therefore throws UOE (UnsupportedOperationException) with this message. This is a deliberate guard, not a bug.

Source

Thrown at processing/src/main/java/org/apache/druid/query/aggregation/any/DoubleAnyAggregatorFactory.java:151

  }

  @Override
  public Comparator getComparator()
  {
    return DoubleSumAggregator.COMPARATOR;
  }

  @Override
  @Nullable
  public Object combine(@Nullable Object lhs, @Nullable Object rhs)
  {
    return lhs;
  }

  @Override
  public AggregateCombiner makeAggregateCombiner()
  {
    throw new UOE("DoubleAnyAggregatorFactory is not supported during ingestion for rollup");
  }

  @Override
  public AggregatorFactory getCombiningFactory()
  {
    return new DoubleAnyAggregatorFactory(name, name);
  }

  @Override
  public Object deserialize(Object object)
  {
    // handle "NaN" / "Infinity" values serialized as strings in JSON
    if (object instanceof String) {
      return Double.parseDouble((String) object);
    }
    return object;
  }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Remove doubleAny from the rollup metricsSpec; use a supported aggregator like doubleSum, doubleMin, doubleMax, or doubleFirst/last depending on intent
  2. If you need to keep an arbitrary value, disable rollup for that datasource so raw rows are stored
  3. Store the raw metric in rollup with a deterministic aggregator and apply doubleAny only at query time on the rolled-up data
  4. If only one row can match a rollup key in practice, doubleFirst may be an acceptable deterministic substitute

Example fix

// before
"metricsSpec": [{ "type": "doubleAny", "name": "v" }]
// after
"metricsSpec": [{ "type": "doubleSum", "name": "v" }]  // or disable rollup
Defensive patterns

Strategy: validation

Validate before calling

// Java: validate spec before submitting ingestion
boolean rollupSafe(IngestionSpec spec) {
  return spec.metricsSpec.stream().noneMatch(a ->
      "doubleAny".equals(a.getType()) && spec.rollup); 
}

Type guard

boolean isRollupCompatible(AggregatorFactory f) {
  return !(f instanceof DoubleAnyAggregatorFactory);
}

Try / catch

try {
  indexBuilder.addAggregator(factory);
} catch (UnsupportedOperationException e) {
  LOGGER.error(e, "Aggregator %s unsupported for rollup ingestion", factory.getName());
  throw new ISE("Replace any-aggregator with a rollup-compatible one");
}

Prevention

When it happens

Trigger: Running ingestion (batch or streaming) with rollup enabled and an aggregator of type "double" with fn "any" (or type "doubleAny") in the metricsSpec; Druid calls makeAggregateCombiner while building the incremental index and immediately throws.

Common situations: Migrating a query-time doubleAny aggregator into an ingestion spec assuming it works there; building rollup tables where users copy query aggregators verbatim into metricsSpec.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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