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
- Use a valid ISO 8601 period such as PT1H (1 hour) or P1D (1 day)
- Remove periodThreshold from the strategy spec if no period threshold is desired
- Validate the string with a Joda Period parser before deploying the config
- 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
- Always write ISO 8601 periods with the leading 'P' (e.g. PT1H, P1D)
- Use config schema validation for query laning specs before deployment
- Never put human-readable durations like "1 hour" in JSON configs
- Unit-test laning strategy deserialization with representative configs
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
- durationThreshold is not a valid ISO 8601 duration, got
- segmentRangeThreshold is not a valid ISO 8601 duration, got
- At least one of baseDir or files should be specified
- bucketSize must be a power of two (from 1 up to 128) but…
- Cannot delete all segment files since Azure Deep Storage…
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)