apache/druid · error · IllegalArgumentException

Duplicate output name

Error message

Duplicate output name[%s]

What it means

The GroupByQuery constructor validates that all dimension output names are unique across the whole query. Adding a second dimension whose getOutputName() duplicates an already-seen name throws IAE 'Duplicate output name[%s]'.

Solutions

  1. Rename one dimension's outputName so each is unique
  2. Use a different extraction/alias for the duplicate dimension or drop the redundant one
  3. If the same underlying column is needed twice with different logic, give each spec a distinct outputName

Example fix

// before
new DefaultDimensionSpec("page", "page"), new DefaultDimensionSpec("page", "page")
// after
new DefaultDimensionSpec("page", "page"), new DefaultDimensionSpec("page", "page2")
Defensive patterns

Strategy: validation

Validate before calling

Set<String> names = new HashSet<>(); for (DimensionSpec d : dims) { if (!names.add(d.getOutputName())) throw new IllegalArgumentException("Duplicate dimension output name: " + d.getOutputName()); }

Type guard

null

Try / catch

try { new GroupByQuery.Builder()...build(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Duplicate output name")) { /* fix query spec */ } throw e; }

Prevention

When it happens

Trigger: Building a GroupByQuery (or deserializing JSON) with two dimensions resolving to the same output name, e.g. two DefaultDimensionSpecs with the same outputName, or a dimension whose outputName duplicates another dimension's.

Common situations: Copy-pasted dimension specs in hand-written JSON queries; programmatic query builders appending dimensions without name checks; column aliasing mistakes (same alias used twice).

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/groupby/GroupByQuery.java:900

      return this;
    }
    final List<AggregatorFactory> optimizedAggs = new ArrayList<>(aggregatorSpecs.size());
    for (AggregatorFactory aggregatorFactory : aggregatorSpecs) {
      optimizedAggs.add(aggregatorFactory.optimizeForSegment(optimizationContext));
    }
    return withAggregatorSpecs(optimizedAggs);
  }

  private static void verifyOutputNames(
      List<DimensionSpec> dimensions,
      List<AggregatorFactory> aggregators,
      List<PostAggregator> postAggregators
  )
  {
    final Set<String> outputNames = new HashSet<>();
    for (DimensionSpec dimension : dimensions) {
      if (!outputNames.add(dimension.getOutputName())) {
        throw new IAE("Duplicate output name[%s]", dimension.getOutputName());
      }
    }

    for (AggregatorFactory aggregator : aggregators) {
      if (!outputNames.add(aggregator.getName())) {
        throw new IAE("Duplicate output name[%s]", aggregator.getName());
      }
    }

    for (PostAggregator postAggregator : postAggregators) {
      if (!outputNames.add(postAggregator.getName())) {
        throw new IAE("Duplicate output name[%s]", postAggregator.getName());
      }
    }

    if (outputNames.contains(ColumnHolder.TIME_COLUMN_NAME)) {
      throw new IAE(
          "'%s' cannot be used as an output name for dimensions, aggregators, or post-aggregators.",

View on GitHub (pinned to 9b90983fd2)