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

NoneGranularity represents 'no' granularity (effectively millisecond-level, unbucketed), so there is no meaningful date formatter to produce. getFormatter() unconditionally throws UnsupportedOperationException to signal that formatting by this granularity type is not a supported operation.

Source

Thrown at processing/src/main/java/org/apache/druid/java/util/common/granularity/NoneGranularity.java:42

import org.joda.time.format.DateTimeFormatter;

/**
 * NoneGranularity does not bucket data
 */
public class NoneGranularity extends Granularity
{
  /**
   * This constructor is public b/c it is serialized and deserialized
   * based on type in GranularityModule
   */
  public NoneGranularity()
  {
  }

  @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 + 1;
  }

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

  @Override
  public long bucketStart(long time)
  {
    return time;

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Use a real granularity (e.g. PeriodGranularity or GranularityType-based) when you need timestamp formatting
  2. Special-case NoneGranularity in your code: format timestamps with DateTimeFormatter directly instead of via the granularity
  3. If you only need bucketing/truncation, note NoneGranularity.increment/truncate are no-ops and avoid the formatter path entirely

Example fix

// before
DateTimeFormatter fmt = granularity.getFormatter(Formatter.Type.DEFAULT);
// after
DateTimeFormatter fmt = (granularity instanceof NoneGranularity)
    ? ISODateTimeFormat.dateTime()
    : granularity.getFormatter(Formatter.Type.DEFAULT);
Defensive patterns

Strategy: type-guard

Validate before calling

if (GranularityType.NONE.equals(granularityType) || granularity instanceof NoneGranularity) { /* do not call getFormatter */ }

Type guard

boolean canFormat = !(granularity instanceof NoneGranularity);

Try / catch

try { fmt = granularity.getFormatter(type); } catch (UnsupportedOperationException e) { fmt = ISODateTimeFormat.dateTime(); }

Prevention

When it happens

Trigger: Calling NoneGranularity.getFormatter(Formatter.Type) — directly or via code paths that format timestamps per granularity, e.g. segment naming, result timestamp serialization, or input row timestamp parsing configured with granularity "NONE".

Common situations: Generic code that calls getFormatter() on any Granularity without special-casing NONE; misconfigured ingestion specs where granularity was set to none but timestamp formatting is required.

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/24801b8d8d12e9ac. Report an issue: GitHub.