{"record":{"id":"d74bcc9050c16c68","repo":"apache/druid","slug":"illegal-probability-s-must-be-strictly-between","errorCode":null,"errorMessage":"Illegal probability[%s], must be strictly between 0 and 1","messagePattern":"Illegal probability\\[(.+?)\\], must be strictly between 0 and 1","errorType":"validation","errorClass":"org.apache.druid.java.util.common.IAE","httpStatus":null,"severity":"error","filePath":"extensions-core/histogram/src/main/java/org/apache/druid/query/aggregation/histogram/QuantilePostAggregator.java","lineNumber":58,"sourceCode":"public class QuantilePostAggregator extends ApproximateHistogramPostAggregator\n{\n  // this doesn't need to handle nulls because the values come from ApproximateHistogram\n  static final Comparator COMPARATOR = Comparator.comparingDouble(o -> ((Number) o).doubleValue());\n\n  private final float probability;\n\n  @JsonCreator\n  public QuantilePostAggregator(\n      @JsonProperty(\"name\") String name,\n      @JsonProperty(\"fieldName\") String fieldName,\n      @JsonProperty(\"probability\") float probability\n  )\n  {\n    super(name, fieldName);\n    this.probability = probability;\n\n    if (probability < 0 || probability > 1) {\n      throw new IAE(\"Illegal probability[%s], must be strictly between 0 and 1\", probability);\n    }\n  }\n\n  @Override\n  public Comparator getComparator()\n  {\n    return COMPARATOR;\n  }\n\n  @Override\n  public Set<String> getDependentFields()\n  {\n    return Sets.newHashSet(fieldName);\n  }\n\n  @Override\n  public Object compute(Map<String, Object> values)\n  {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/histogram/src/main/java/org/apache/druid/query/aggregation/histogram/QuantilePostAggregator.java#L40-L76","documentation":"The QuantilePostAggregator constructor validates that the probability is strictly between 0 and 1 and throws IllegalArgumentException otherwise. A quantile is undefined outside (0,1), so invalid constructor arguments are rejected immediately at query-spec parsing time.","triggerScenarios":"Constructing QuantilePostAggregator programmatically or via JSON with probability <= 0 or >= 1 (including NaN outside range checks like Infinity), e.g. probability: 1.0 or 0.","commonSituations":"Hand-written query JSON using 0.5f mis-typed, generated specs computing probability as a ratio that can hit 0 or 1, or config-driven percentiles where 0 and 100 were not converted to 0.x fractions.","solutions":["Set probability to a value strictly between 0 and 1, e.g. 0.5 or 0.95.","If converting from percent, divide by 100 and clamp away from the bounds (0 and 100 percent are invalid).","Add validation upstream before building the query spec."],"exampleFix":"// before\n{\"type\": \"quantile\", \"fieldName\": \"h\", \"probability\": 1.0}\n// after\n{\"type\": \"quantile\", \"fieldName\": \"h\", \"probability\": 0.99}","handlingStrategy":"validation","validationCode":"if (!(probability > 0 && probability < 1)) {\n  throw new IllegalArgumentException(\"probability must be strictly between 0 and 1, got \" + probability);\n}","typeGuard":"boolean isValidProbability(double p) {\n  return p > 0.0 && p < 1.0;\n}","tryCatchPattern":"try {\n  QuantilePostAggregator q = new QuantilePostAggregator(name, fieldName, probability);\n} catch (IllegalArgumentException e) {\n  // clamp/correct probability and retry\n}","preventionTips":["Clamp percent-to-fraction conversions away from 0 and 1 bounds.","Validate probability inputs at config-load time.","Remember 0.0 and 1.0 are invalid; use min/max post-aggs for extremes."],"tags":["druid","histogram","post-aggregator","validation"],"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-14T11:17:12.474Z"}