apache/druid · error · UnsupportedOperationException

Period cannot be converted to milliseconds as some fields ma

Error message

Period cannot be converted to milliseconds as some fields mays vary in length with chronology 

What it means

PeriodGranularity.truncate() can only bucket timestamps arithmetically when the period's total duration is expressible as a fixed number of milliseconds. Periods containing calendar-varying fields (months, years, and with some chronologies weeks/days) have no fixed millisecond length, so truncateMillisPeriod throws UnsupportedOperationException naming the chronology.

Source

Thrown at processing/src/main/java/org/apache/druid/java/util/common/granularity/PeriodGranularity.java:604

        current = chronology.add(period, current, -1);
      } while (t < current);
    }
    return current;
  }

  private long truncateMillisPeriod(final long t)
  {
    // toStandardDuration assumes days are always 24h, and hours are always 60 minutes,
    // which may not always be the case, e.g if there are daylight saving changes.
    if (chronology.days().isPrecise() && chronology.hours().isPrecise()) {
      final long millis = period.toStandardDuration().getMillis();
      long offset = t % millis - origin % millis;
      if (offset < 0) {
        offset += millis;
      }
      return t - offset;
    } else {
      throw new UnsupportedOperationException(
          "Period cannot be converted to milliseconds as some fields mays vary in length with chronology " + chronology
      );
    }
  }

  @Override
  public void serialize(JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
      throws IOException
  {
    // Retain the same behavior as before #3850.
    // i.e. when Granularity class was an enum.
    if (GranularityType.isStandard(this)) {
      jsonGenerator.writeString(GranularityType.fromPeriod(getPeriod()).toString());
    } else {
      jsonGenerator.writeStartObject();
      jsonGenerator.writeStringField("type", "period");
      jsonGenerator.writeObjectField("period", getPeriod());
      jsonGenerator.writeObjectField("timeZone", getTimeZone());

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Use ISO chronology with UTC and periods made of fixed-length fields (weeks, days, hours, minutes, seconds, millis) for truncation-dependent code paths
  2. For month/year bucketing, keep the standard Granularity enum (MONTH/YEAR) implementations that handle calendar bucketing via Chronology-based truncation instead of the millis path
  3. Verify the granularity's chronology is set to DateTimeZones.UTC / ISOChronology so fixed-period truncation applies

Example fix

// before
Granularity g = new PeriodGranularity(Period.parse("P1M"), origin, chronology); // thrown in truncate
// after
Granularity g = GranularityType.MONTH.getDefaultGranularity(); // calendar-aware month bucketing
Defensive patterns

Strategy: validation

Validate before calling

Period p = granularity.getPeriod();
boolean fixedLength = p.getMonths() == 0 && p.getYears() == 0;
// if (!fixedLength) avoid truncate-millis path or use Granularity.MONTH/YEAR

Type guard

boolean truncatable = granularity.getPeriod().getMonths() == 0 && granularity.getPeriod().getYears() == 0;

Try / catch

try { long b = granularity.truncate(ts); } catch (UnsupportedOperationException e) { /* use calendar-aware Granularity.MONTH/YEAR */ }

Prevention

When it happens

Trigger: Truncating a timestamp against a PeriodGranularity whose period contains months or years (e.g. Period.parse("P1M") or "P1Y") — called via truncate/bucketStart during query time-bucketing or segment allocation.

Common situations: Month or year query granularity on data where the truncation path expects fixed-length periods; chronology (e.g. non-ISO or UTC-less) configurations that make week/day fields variable length.

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