{"record":{"id":"48945d64d71274a0","repo":"apache/druid","slug":"failed-to-get-object-summaries-from-s3-bucket-s","errorCode":null,"errorMessage":"Failed to get object summaries from S3 bucket[%s], prefix[%s]; S3 error: %s","messagePattern":"Failed to get object summaries from S3 bucket\\[(.+?)\\], prefix\\[(.+?)\\]; S3 error: (.+?)","errorType":"exception","errorClass":"DruidRuntimeException","httpStatus":null,"severity":"error","filePath":"extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/ObjectSummaryIterator.java","lineNumber":133,"sourceCode":"    continuationToken = null;\n  }\n\n  private void fetchNextBatch()\n  {\n    try {\n      ListObjectsV2Request request = ListObjectsV2Request.builder()\n          .bucket(currentBucket)\n          .prefix(currentPrefix)\n          .maxKeys(maxListingLength)\n          .continuationToken(continuationToken)\n          .build();\n\n      result = S3Utils.retryS3Operation(() -> s3Client.listObjectsV2(request), maxRetries);\n      continuationToken = result.nextContinuationToken();\n      objectSummaryIterator = result.contents().iterator();\n    }\n    catch (S3Exception e) {\n      throw new RE(\n          e,\n          \"Failed to get object summaries from S3 bucket[%s], prefix[%s]; S3 error: %s\",\n          currentBucket,\n          currentPrefix,\n          e.getMessage()\n      );\n    }\n    catch (Exception e) {\n      throw new RE(\n          e,\n          \"Failed to get object summaries from S3 bucket[%s], prefix[%s]\",\n          currentBucket,\n          currentPrefix\n      );\n    }\n  }\n\n  /**","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/ObjectSummaryIterator.java#L115-L151","documentation":"ObjectSummaryIterator.fetchNextBatch lists S3 objects page-by-page with listObjectsV2 wrapped in S3Utils.retryS3Operation. When the listing still fails after maxRetries with an S3Exception, Druid wraps it in a ReportedException (RE) that includes the bucket, prefix, and the S3 error message (e.g. AccessDenied, NoSuchBucket, throttling). This error surfaces during input-source split listing, so ingestion/queries against the S3 input source fail at the planning/listing stage.","triggerScenarios":"Calling the constructor or advancing the iterator (constructorPostProcessing/advanceObjectSummary -> fetchNextBatch) where s3Client.listObjectsV2 throws S3Exception on every attempt up to maxRetries — e.g. 403 AccessDenied, 404 NoSuchBucket, 503 SlowDown throttling, or network errors exceeding the retry budget.","commonSituations":"IAM credentials lacking s3:ListBucket on the bucket/prefix; typo in bucket name or region; S3 request-rate throttling on buckets with many prefixes; expired session credentials (STS); VPC endpoint or proxy blocking S3 traffic.","solutions":["Grant the task's IAM credentials s3:ListBucket permission (with the prefix condition) for the target bucket.","Verify the bucket name, region, and endpoint configuration in the S3 input source / druid.s3.* properties.","If the error is SlowDown/throttling, reduce concurrent listing workers, narrow prefixes, or increase retry limits (druid.s3.maxRetries / client retry policy).","Refresh or fix credentials (expired STS tokens, wrong access/secret key) and re-run the task."],"exampleFix":"// before (IAM policy)\n{\"Effect\":\"Deny\",\"Action\":\"s3:ListBucket\",\"Resource\":\"arn:aws:s3:::my-bucket\"}\n// after\n{\"Effect\":\"Allow\",\"Action\":\"s3:ListBucket\",\"Resource\":\"arn:aws:s3:::my-bucket\",\n \"Condition\":{\"StringLike\":{\"s3:prefix\":[\"data/*\"]}}}","handlingStrategy":"retry","validationCode":"// preflight check before running the job\nHeadBucketRequest head = HeadBucketRequest.builder().bucket(bucket).build();\ns3Client.headBucket(head); // throws S3Exception 403/404 early if bucket is inaccessible/nonexistent","typeGuard":null,"tryCatchPattern":"try {\n  iterator.next(); // triggers listing\n} catch (ReportedException e) {\n  Throwable cause = e.getCause();\n  if (cause instanceof S3Exception s3e) {\n    int status = s3e.statusCode();\n    if (status == 403 || status == 404) {\n      throw new IllegalStateException(\"Check bucket name/IAM ListBucket permission\", e);\n    }\n    if (status == 503) {\n      // backoff and retry with fewer concurrent listings\n    }\n  }\n  throw e;\n}","preventionTips":["Grant s3:ListBucket (with prefix condition) to the ingestion task role","Verify bucket name and region before launching tasks","Back off on 503 SlowDown and reduce parallel prefix listings","Monitor for expired STS credentials in long-running tasks","Tune druid.s3 retry settings to tolerate transient S3 errors"],"tags":["s3","aws-sdk","retry-exhausted","permissions","listing"],"backgroundTag":"http-error-response","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}