{"record":{"id":"b943ea24b9878c12","repo":"apache/druid","slug":"failed-to-get-s3-object-for-bucket-s-key-s-r","errorCode":null,"errorMessage":"Failed to get s3 object for bucket[%s], key[%s], range[bytes=%d-%d]","messagePattern":"Failed to get s3 object for bucket\\[(.+?)\\], key\\[(.+?)\\], range\\[bytes=(.+?)-(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException (ISE)","httpStatus":null,"severity":"error","filePath":"extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3SegmentRangeReader.java","lineNumber":136,"sourceCode":"\n    @Override\n    public InputStream open(RangeRequest request, long start) throws IOException\n    {\n      final long absoluteStart = request.offset + start;\n      final long absoluteEnd = request.offset + request.length - 1;\n      if (absoluteStart > absoluteEnd) {\n        // Logically nothing left to read, only reachable if a retry fires after the consumer drained the entire\n        // range successfully, which shouldn't happen in practice. Returning empty keeps us robust either way.\n        return new ByteArrayInputStream(new byte[0]);\n      }\n      final GetObjectRequest.Builder requestBuilder = GetObjectRequest.builder()\n          .bucket(bucket)\n          .key(request.objectKey)\n          .range(AwsBytesRange.of(absoluteStart, absoluteEnd).getBytesRange());\n      try {\n        final InputStream s3Object = s3Client.getObject(requestBuilder);\n        if (s3Object == null) {\n          throw new ISE(\n              \"Failed to get s3 object for bucket[%s], key[%s], range[bytes=%d-%d]\",\n              bucket,\n              request.objectKey,\n              absoluteStart,\n              absoluteEnd\n          );\n        }\n        return s3Object;\n      }\n      catch (S3Exception e) {\n        throw new IOException(e);\n      }\n    }\n  }\n}\n","sourceCodeStart":118,"sourceCodeEnd":152,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3SegmentRangeReader.java#L118-L152","documentation":"S3SegmentRangeReader.open issues a GetObject with a byte range; the SDK returned a null InputStream despite not throwing, which is an unexpected/failed fetch of the ranged object. The reader throws ISE naming bucket, key, and byte range.","triggerScenarios":"Calling open() on a segment range when s3Client.getObject returns null (object vanished between check and read, or a proxy/client quirk yields a null body).","commonSituations":"Segment deleted by retention/lifecycle rules while being read; S3-compatible storage (MinIO) returning null body on range GET; race with segment replacement during re-indexing.","solutions":["Verify the object still exists at bucket/key before reading.","Check S3 lifecycle/retention policies that might delete segments mid-read.","If using S3-compatible storage, test range GET behavior there.","Retry the read; the underlying RetryUtils may mask transient nulls upstream."],"exampleFix":"// before\nInputStream in = rangeReader.open(request);\n// after\nif (!S3Utils.isObjectInBucket(s3Client, bucket, key)) {\n  throw new IllegalStateException(\"object gone: \" + bucket + \"/\" + key);\n}\nInputStream in = rangeReader.open(request);","handlingStrategy":"try-catch","validationCode":"if (!S3Utils.isObjectInBucket(s3Client, bucket, key)) throw new IllegalStateException(\"object missing: \" + bucket + \"/\" + key);","typeGuard":"InputStream in = s3Client.getObject(req);\nif (in == null) throw new IOException(\"null body for \" + req.bucket() + \"/\" + req.key());","tryCatchPattern":"try { in = rangeReader.open(req); } catch (IllegalStateException e) { /* object vanished: re-check existence, refresh segment locator */ }","preventionTips":["Don't delete segments while queries may read them","Beware lifecycle policies racing reads","Test range GET support when using S3-compatible stores"],"tags":["s3","range-read","null-response","segments"],"backgroundTag":"empty-response-body","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"}