apache/druid · error · IllegalArgumentException

periodThreshold is not a valid ISO 8601 period, got

Error message

periodThreshold is not a valid ISO 8601 period, got [<periodThresholdString>]

What it means

WeightedQueryLaningStrategy's constructor parses the optional periodThreshold config string as a Joda-Time Period. If the string is not a valid ISO 8601 period, it throws IllegalArgumentException with the offending value so the operator can correct the laning configuration before the strategy is used.

Solutions

  1. Use a valid ISO 8601 period such as PT1H (1 hour) or P1D (1 day)
  2. Remove periodThreshold from the strategy spec if no period threshold is desired
  3. Validate the string with a Joda Period parser before deploying the config
  4. Review the strategy's JSON spec for stray whitespace or wrong fields

Example fix

// before
{"type":"sql#weighted","periodThreshold":"1 hour"}
// after
{"type":"sql#weighted","periodThreshold":"PT1H"}
Defensive patterns

Strategy: validation

Validate before calling

try { new org.joda.time.Period(periodThresholdString); } catch (IllegalArgumentException e) { /* reject config */ }

Prevention

When it happens

Trigger: Configuring maxQueryDurationOnTier/periodThreshold with a malformed value such as "PT", "1-hour", "3600" (bare number without unit) or other non-ISO-8601 text in the query laning strategy JSON spec.

Common situations: Hand-written laning specs with typos, authors confusing ISO 8601 duration format with human-readable time strings or milliseconds, using 'd'/'h' shorthand without the required P prefix.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


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

Appendix: source

Thrown at server/src/main/java/org/apache/druid/server/scheduling/WeightedQueryLaningStrategy.java:131

      @JsonProperty("durationThreshold") @Nullable String durationThresholdString,
      @JsonProperty("segmentCountThreshold") @Nullable Integer segmentCountThreshold,
      @JsonProperty("segmentRangeThreshold") @Nullable String segmentRangeThresholdString,
      @JsonProperty("lanes") Map<String, LaneConfig> lanes,
      @JsonProperty("periodWeight") @Nullable Integer periodWeight,
      @JsonProperty("durationWeight") @Nullable Integer durationWeight,
      @JsonProperty("segmentCountWeight") @Nullable Integer segmentCountWeight,
      @JsonProperty("segmentRangeWeight") @Nullable Integer segmentRangeWeight
  )
  {
    final Period parsedPeriod;
    if (periodThresholdString == null) {
      parsedPeriod = null;
    } else {
      try {
        parsedPeriod = new Period(periodThresholdString);
      }
      catch (IllegalArgumentException e) {
        throw new IllegalArgumentException(
            "periodThreshold is not a valid ISO 8601 period, got [" + periodThresholdString + "]"
        );
      }
    }
    final Duration parsedDuration;
    if (durationThresholdString == null) {
      parsedDuration = null;
    } else {
      try {
        parsedDuration = new Period(durationThresholdString).toStandardDuration();
      }
      catch (IllegalArgumentException | UnsupportedOperationException e) {
        throw new IllegalArgumentException(
            "durationThreshold is not a valid ISO 8601 duration, "
            + "got [" + durationThresholdString + "]"
        );
      }
    }

View on GitHub (pinned to 9b90983fd2)