apache/druid · error · IllegalArgumentException

period must not be negative. Supplied period:

Error message

period must not be negative. Supplied period: 

What it means

Compaction rules (reindexing rules) that use a Period require a non-negative period to define how far back data is retained/compacted. When the period contains months or years (variable-length components that cannot be converted to a fixed duration), validatePeriodIsNonNegative checks each component and throws this IllegalArgumentException if any part is negative.

Source

Thrown at server/src/main/java/org/apache/druid/server/compaction/AbstractReindexingRule.java:82

  /**
   * Validates that a period represents a non-negative duration (>= 0).
   * <p>
   * Zero periods (P0D) are allowed - they indicate rules that should apply immediately to all data.
   * Negative periods are rejected as they would be nonsensical.
   * <p>
   * For periods with precise units (days, hours, minutes, seconds), validates by converting
   * to a standard duration. For periods with variable-length units (months, years), validates
   * that no components are negative, since these cannot be converted to a precise duration.
   *
   * @param period the period to validate
   * @throws IllegalArgumentException if the period is negative
   */
  private static void validatePeriodIsNonNegative(Period period)
  {
    if (hasMonthsOrYears(period)) {
      if (isPeriodNegative(period)) {
        throw new IllegalArgumentException("period must not be negative. Supplied period: " + period);
      }
    } else {
      if (period.toStandardDuration().getMillis() < 0) {
        throw new IllegalArgumentException("period must not be negative. Supplied period: " + period);
      }
    }
  }

  /**
   * Checks if a period with variable-length components (months/years) has any negative components.
   * <p>
   * This is purposely an unscientific check that simply ensures no negative values are present in any component of the period.
   * It should be "good enough" for almost all reasonable use cases.
   *
   * @param period the period to check
   * @return true if any component is negative
   */
  private static boolean isPeriodNegative(Period period)

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Correct the period string in the rule to a non-negative value, e.g. change "P-1M" to "P1M".
  2. Re-submit the rule via POST /druid/coordinator/v1/rules with the fixed period.
  3. Validate the Period object before constructing the rule if rules are generated in code.

Example fix

// before
{"type": "loadByPeriod", "period": "P-1M"}
// after
{"type": "loadByPeriod", "period": "P1M"}
Defensive patterns

Strategy: validation

Validate before calling

function validatePeriod(p) {
  if (/[YM]/.test(p) && /-/.test(p.replace(/^P/, ''))) {
    throw new Error(`period must not be negative: ${p}`);
  }
}
validatePeriod(rule.period);

Type guard

function isNonNegativePeriodString(p) {
  return /^P(?!.*-)/.test(p);
}

Try / catch

try {
  coordinator.submitRule(rule);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("period must not be negative")) {
    log.error(`Fix rule period: ${e.getMessage()}`);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Submitting a load/compaction rule JSON with a period containing months or years whose components are negative, e.g. "period": "P-1M" or "-PT24H" combined with month/year fields.

Common situations: Typo'd ISO-8601 period strings in rule JSON (a stray leading '-' or '-' inside the period); programmatically built Period objects from signed durations; copy-pasted rules edited by hand in the Druid console.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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