{"record":{"id":"f5db76d99a077f5c","repo":"apache/druid","slug":"granularity-is-not-supported-s","errorCode":null,"errorMessage":"Granularity is not supported. [%s]","messagePattern":"Granularity is not supported\\. \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/granularity/GranularityType.java","lineNumber":201,"sourceCode":"      }\n    }\n    return false;\n  }\n\n  /**\n   * Note: This is only an estimate based on the values in period.\n   * This will not work for complicated periods that represent say 1 year 1 day\n   */\n  public static GranularityType fromPeriod(Period period)\n  {\n    int[] vals = period.getValues();\n    int index = -1;\n    for (int i = 0; i < vals.length; i++) {\n      if (vals[i] != 0) {\n        if (index < 0) {\n          index = i;\n        } else {\n          throw new IAE(\"Granularity is not supported. [%s]\", period);\n        }\n      }\n    }\n\n    switch (index) {\n      case 0:\n        return GranularityType.YEAR;\n      case 1:\n        if (vals[index] == 3) {\n          return GranularityType.QUARTER;\n        } else if (vals[index] == 1) {\n          return GranularityType.MONTH;\n        }\n        break;\n      case 2:\n        return GranularityType.WEEK;\n      case 3:\n        return GranularityType.DAY;","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/granularity/GranularityType.java#L183-L219","documentation":"GranularityType.fromPeriod() converts a Joda Period into a GranularityType enum only when the period has exactly one non-zero component (e.g. PT1H or P1D). While scanning the period's field values it throws this IAE if it finds a second non-zero field, because a compound period like 'P1DT2H' does not map to any single granularity bucket.","triggerScenarios":"Calling GranularityType.fromPeriod(new Period(\"P1DT2H\")) or any Period with two or more non-zero fields (weeks+days, hours+minutes, etc.). Also thrown when the period's fields don't align with the enum's supported magnitudes (e.g. PT90M after the switch falls through).","commonSituations":"Users supply compound query granularities like 'P1W2D' or 'PT1H30M' in JSON query specs or ingestion granularity configs; misconfigured period strings from external systems that normalize durations into compound periods.","solutions":["Use a simple Period with exactly one non-zero field, e.g. Period.parse(\"PT2H\") instead of \"PT1H30M\"","If a compound bucket is needed, pick the larger unit and set origin/timeZone on PeriodGranularity instead, or use an arbitrary-duration approach","Parse the input period first and validate that at most one of getYears()..getMillis() is non-zero before calling fromPeriod"],"exampleFix":"// before\nGranularity gran = GranularityType.fromPeriod(Period.parse(\"P1DT2H\"));\n// after\nGranularity gran = GranularityType.fromPeriod(Period.parse(\"P1D\")); // single non-zero field","handlingStrategy":"validation","validationCode":"static boolean isSimplePeriod(Period p) {\n  int nz = 0;\n  int[] f = {p.getYears(), p.getMonths(), p.getWeeks(), p.getDays(), p.getHours(), p.getMinutes(), p.getSeconds(), p.getMillis()};\n  for (int v : f) { if (v != 0) nz++; }\n  return nz == 1;\n}\n// call: if (!isSimplePeriod(period)) throw new IllegalArgumentException(...);","typeGuard":"if (GranularityType.fromPeriod(period) == null || !isSimplePeriod(period)) { /* fallback */ }","tryCatchPattern":"try { t = GranularityType.fromPeriod(period); } catch (IllegalArgumentException e) { /* fall back to PeriodGranularity or reject config */ }","preventionTips":["Reject compound periods (multiple non-zero fields) at config parse time","Prefer Granularity enum JSON values over raw period strings in specs","Unit-test granularity parsing with all user-facing config values"],"tags":["granularity","period","invalid-argument","druid"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}