apache/druid · error · UnsupportedOperationException

This method should not be invoked for this granularity type

Error message

This method should not be invoked for this granularity type

What it means

DurationGranularity buckets time purely by a fixed duration with an optional origin; it has no named period pattern for parsing dates from file paths, so getFormatter() throws UnsupportedOperationException('This method should not be invoked for this granularity type'). Only period-based granularities (e.g. day/month) implement path formatting.

Source

Thrown at processing/src/main/java/org/apache/druid/java/util/common/granularity/DurationGranularity.java:71

    this.origin = origin % duration;
  }

  @JsonProperty("duration")
  public long getDuration()
  {
    return duration;
  }

  @JsonProperty("origin")
  public DateTime getOrigin()
  {
    return DateTimes.utc(origin);
  }

  @Override
  public DateTimeFormatter getFormatter(Formatter type)
  {
    throw new UnsupportedOperationException("This method should not be invoked for this granularity type");
  }

  @Override
  public long increment(long time)
  {
    return time + duration;
  }

  @Override
  public DateTime increment(DateTime time)
  {
    return time.plus(duration);
  }

  @Override
  public long bucketStart(long t)
  {
    final long duration = getDurationMillis();

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Switch the spec to a period granularity (e.g. {"type":"period","period":"PT1H"}) when using path-based date extraction
  2. Special-case DurationGranularity at the call site and derive timestamps differently (e.g. compute bucket from an explicit timestamp)
  3. Verify the granularity JSON: duration granularities are for bucketing arithmetic, not path formatting
  4. If the caller is your own code, implement formatter logic only for granularities that support it and throw a clearer config error otherwise

Example fix

// before
"granularity": {"type": "duration", "duration": 3600000}
// after (for path-based ingestion)
"granularity": {"type": "period", "period": "PT1H"}
Defensive patterns

Strategy: type-guard

Validate before calling

if (granularity instanceof DurationGranularity) {
  throw new IllegalArgumentException("Duration granularity has no path formatter; use a period granularity");
}

Type guard

boolean hasPathFormatter(Granularity g) {
  return g instanceof PeriodGranularity;
}

Try / catch

try {
  formatter = granularity.getFormatter(type);
} catch (UnsupportedOperationException e) {
  // duration granularity: compute buckets arithmetically instead of formatting
}

Prevention

When it happens

Trigger: Calling DurationGranularity.getFormatter(type) — typically from path-based segment/file date extraction code handed a duration-type granularity (e.g. {"type":"duration","duration":3600000}).

Common situations: Ingestion specs using duration granularity with a path parser that expects period granularity; code generic over Granularity assuming getFormatter exists; JSON granularity config with type 'duration' fed into path-partitioning logic.

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/3d1105c9dde58d4f. Report an issue: GitHub.