{"record":{"id":"7ed44949a17764c2","repo":"apache/druid","slug":"cannot-list-directory-s","errorCode":null,"errorMessage":"Cannot list directory [%s]","messagePattern":"Cannot list directory \\[(.+?)\\]","errorType":"exception","errorClass":"IOException (IOE)","httpStatus":null,"severity":"error","filePath":"extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3DataSegmentPusher.java","lineNumber":114,"sourceCode":"      }\n      catch (S3Exception e) {\n        throw handlePushServiceException(e, indexSize);\n      }\n      catch (Exception e) {\n        throw new RuntimeException(e);\n      }\n    }\n    finally {\n      log.debug(\"Deleting temporary cached index.zip\");\n      zipOutFile.delete();\n    }\n  }\n\n  private DataSegment pushNoZip(File indexFilesDir, DataSegment baseSegment, String s3Path) throws IOException\n  {\n    final File[] files = indexFilesDir.listFiles();\n    if (files == null) {\n      throw new IOE(\"Cannot list directory [%s]\", indexFilesDir);\n    }\n\n    long size = 0;\n    for (final File file : files) {\n      if (file.isFile()) {\n        size += file.length();\n\n        try {\n          S3Utils.retryS3Operation(\n              () -> {\n                S3Utils.uploadFileIfPossible(s3Client, config.getDisableAcl(), config.getBucket(), s3Path + file.getName(), file);\n                return null;\n              }\n          );\n        }\n        catch (S3Exception e) {\n          throw handlePushServiceException(e, file.length());\n        }","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3DataSegmentPusher.java#L96-L132","documentation":"S3DataSegmentPusher.pushNoZip lists the segment directory's files with File.listFiles(); a null return means the directory could not be read (does not exist, is a file, or I/O error). The pusher throws this IOException instead of silently pushing nothing.","triggerScenarios":"Calling push/pushToPath with an indexFilesDir that was deleted, never created, or is not a directory, so File.listFiles() returns null.","commonSituations":"Task working directory cleaned up mid-push by external cleanup; permissions problem on the deep storage staging dir; bug in a custom segment publisher writing to the wrong path.","solutions":["Ensure the segment files directory exists and is readable before pushing.","Check filesystem permissions on the directory and its parents.","Look for concurrent cleanup jobs deleting the task's working directory.","Verify disk health (I/O errors also make listFiles return null)."],"exampleFix":"// before\npusher.push(new File(\"/missing/dir\"), segment);\n// after\nFile dir = new File(\"/missing/dir\");\nif (!dir.isDirectory()) {\n  throw new IllegalStateException(\"Segment dir missing: \" + dir);\n}\npusher.push(dir, segment);","handlingStrategy":"validation","validationCode":"if (dir == null || !dir.isDirectory()) throw new IllegalArgumentException(\"not a readable directory: \" + dir);","typeGuard":null,"tryCatchPattern":"try { pusher.push(dir, segment); } catch (IOException e) { /* check directory readability before retrying */ }","preventionTips":["Assert segment dir is a readable directory before push","Avoid external cleanup racing ingestion tasks","Check disk/mount health in task launchers"],"tags":["io","filesystem","s3","push"],"backgroundTag":"directory-not-found","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"}