{"record":{"id":"86ba415f8498f9f2","repo":"apache/druid","slug":"maxtries-must-be-greater-than-1","errorCode":null,"errorMessage":"maxTries must be greater than 1","messagePattern":"maxTries must be greater than 1","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/data/input/impl/RetryingInputStream.java","lineNumber":92,"sourceCode":"  }\n\n  @VisibleForTesting\n  RetryingInputStream(\n      T object,\n      ObjectOpenFunction<T> objectOpenFunction,\n      Predicate<Throwable> retryCondition,\n      @Nullable Integer maxTries,\n      boolean doWait\n  ) throws IOException\n  {\n    this.object = Preconditions.checkNotNull(object, \"object\");\n    this.objectOpenFunction = Preconditions.checkNotNull(objectOpenFunction, \"objectOpenFunction\");\n    this.retryCondition = Preconditions.checkNotNull(retryCondition, \"retryCondition\");\n    this.maxTries = maxTries == null ? RetryUtils.DEFAULT_MAX_TRIES : maxTries;\n    this.doWait = doWait;\n\n    if (this.maxTries <= 1) {\n      throw new IAE(\"maxTries must be greater than 1\");\n    }\n    openWithRetry(0);\n  }\n\n  private void openIfNeeded() throws IOException\n  {\n    if (delegate == null) {\n      openWithRetry(startOffset);\n    }\n  }\n\n  private void openWithRetry(final long offset) throws IOException\n  {\n    for (int nTry = 0; nTry < maxTries; nTry++) {\n      try {\n        delegate = new CountingInputStream(objectOpenFunction.open(object, offset));\n        break;\n      }","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/data/input/impl/RetryingInputStream.java#L74-L110","documentation":"RetryingInputStream validates its retry policy in the constructor and requires maxTries to be greater than 1, since with a single try there is no point in the retry wrapper. Values of 0, 1, or negative throw this IllegalArgumentException.","triggerScenarios":"Constructing RetryingInputStream with maxTries <= 1 (e.g. 0, 1, or negative), often from deserialized inputFormat/split specs where maxRetry or httpMaxRetry was set to 1 or 0.","commonSituations":"Config authors setting maxRetry: 1 intending 'one attempt', property files with 0 or unset-then-defaulted values, programmatic builders passing Integer constants like 1.","solutions":["Set maxTries to at least 2 (Druid's default is RetryUtils.DEFAULT_MAX_TRIES)","Leave maxTries null to use the default instead of setting 1","Fix ingestion spec fields like http.maxRetry to a valid value >= 2"],"exampleFix":"// before\nnew RetryingInputStream(openFn, retryCond, 1, doWait);\n// after\nnew RetryingInputStream(openFn, retryCond, 3, doWait);","handlingStrategy":"validation","validationCode":"if (maxTries != null && maxTries <= 1) { throw new IllegalArgumentException(\"maxTries must be > 1\"); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Leave maxTries null to use the default","Never configure retry counts of 0 or 1 for RetryingInputStream","Validate spec numeric fields against minimums before submission"],"tags":["retry","config","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-17T15:17:12.973Z"}