apache/druid · warning

Failed to remove output directory

Error message

Failed to remove output directory [%s] for segment pulled from [%s]

What it means

OssDataSegmentPuller.getSegmentFiles() downloads a segment from Aliyun OSS into a temp output directory; if the download/extract fails it tries to delete that directory, and logs this warning when the deletion itself throws IOException. The original SegmentLoadingException is still thrown — this warning only indicates leftover temp files on disk.

Solutions

  1. Fix the root cause of the pull failure (check OSS object exists, credentials, endpoint config)
  2. Manually delete the leftover temp directory under the druid segment cache/tmp location
  3. Check filesystem permissions and free space for the cache directory
  4. Avoid NFS for segment cache dirs if deletion errors persist
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight OSS access before segment load
 OSSObject obj = ossClient.getObject(bucket, key); // throws on missing object/bad creds

Try / catch

try {
  Map<String,File> files = puller.getSegmentFiles(segment);
} catch (SegmentLoadingException e) {
  log.warn(e, "Segment pull from OSS failed; leftover temp dir possible");
}

Prevention

When it happens

Trigger: A segment pull from OSS fails (missing object, 404, credentials error, corrupt zip) AND FileUtils.deleteDirectory(outDir) cannot delete the temp dir (locked files, permission issues, NFS staleness).

Common situations: Wrong OSS bucket/path config or expired STS credentials causing pull failures; read-only or full disk; segment cache dir on NFS where unlink fails; concurrent processes holding files in outDir.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/53c787c91fa33cc0. Report an issue: GitHub.

Appendix: source

Thrown at extensions-contrib/aliyun-oss-extensions/src/main/java/org/apache/druid/storage/aliyun/OssDataSegmentPuller.java:129

        log.info("Loaded %d bytes from [%s] to [%s]", result.size(), ossCoords.toString(), outDir.getAbsolutePath());
        return result;
      }
      if (CompressionUtils.isGz(ossCoords.getPath())) {
        final String fname = Files.getNameWithoutExtension(uri.getPath());
        final File outFile = new File(outDir, fname);

        final FileUtils.FileCopyResult result = CompressionUtils.gunzip(byteSource, outFile, OssUtils.RETRYABLE);
        log.info("Loaded %d bytes from [%s] to [%s]", result.size(), ossCoords.toString(), outFile.getAbsolutePath());
        return result;
      }
      throw new IAE("Do not know how to load file type at [%s]", uri.toString());
    }
    catch (Exception e) {
      try {
        FileUtils.deleteDirectory(outDir);
      }
      catch (IOException ioe) {
        log.warn(
            ioe,
            "Failed to remove output directory [%s] for segment pulled from [%s]",
            outDir.getAbsolutePath(),
            ossCoords.toString()
        );
      }
      throw new SegmentLoadingException(e, e.getMessage());
    }
  }

  @Override
  public InputStream getInputStream(URI uri) throws IOException
  {
    try {
      return buildFileObject(uri).openInputStream();
    }
    catch (OSSException e) {
      throw new IOE(e, "Could not load URI [%s]", uri);

View on GitHub (pinned to 9b90983fd2)