apache/druid · error · SegmentLoadingException

Unable to unzip file [%s]

Error message

Unable to unzip file [%s]

What it means

LocalDataSegmentPuller.getSegmentFiles throws SegmentLoadingException when a locally stored segment ending in .zip fails to unzip with an IOException. The segment's index.zip could not be extracted to the target directory, usually because the archive is corrupt, truncated, or unreadable.

Source

Thrown at server/src/main/java/org/apache/druid/segment/loading/LocalDataSegmentPuller.java:175

      }
    } else if (CompressionUtils.isZip(sourceFile.getName())) {
      try {
        final FileUtils.FileCopyResult result = CompressionUtils.unzip(
            Files.asByteSource(sourceFile),
            dir,
            shouldRetryPredicate(),
            false
        );
        log.info(
            "Unzipped %d bytes from [%s] to [%s]",
            result.size(),
            sourceFile.getAbsolutePath(),
            dir.getAbsolutePath()
        );
        return result;
      }
      catch (IOException e) {
        throw new SegmentLoadingException(e, "Unable to unzip file [%s]", sourceFile.getAbsolutePath());
      }
    } else if (CompressionUtils.isGz(sourceFile.getName())) {
      final File outFile = new File(dir, CompressionUtils.getGzBaseName(sourceFile.getName()));
      final FileUtils.FileCopyResult result = CompressionUtils.gunzip(
          Files.asByteSource(sourceFile),
          outFile,
          shouldRetryPredicate()
      );
      log.info(
          "Gunzipped %d bytes from [%s] to [%s]",
          result.size(),
          sourceFile.getAbsolutePath(),
          outFile.getAbsolutePath()
      );
      return result;
    } else {
      throw new SegmentLoadingException("Do not know how to handle source [%s]", sourceFile.getAbsolutePath());
    }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check `unzip -t <segment index.zip>` to confirm corruption.
  2. Verify free disk space on the Druid segment cache directory.
  3. Re-push the segment (re-run the task or use the segments REST API to reset) or re-copy it from a healthy replica.
  4. Ensure the Druid process has read access to the source zip and write access to the target dir.

Example fix

// before: extracting a zip corrupted by scp without binary mode
scp oldhost:/ds/druid/.../index.zip /ds/druid/.../index.zip
// after: verify and re-copy preserving binary
rsync -a --checksum oldhost:/ds/druid/.../index.zip /ds/druid/.../
unzip -t /ds/druid/.../index.zip
Defensive patterns

Strategy: try-catch

Validate before calling

final File zip = new File((String) segment.getLoadSpec().get("path"));
if (!zip.isFile() || zip.length() == 0 || !zip.canRead()) throw new IllegalStateException("index.zip missing or unreadable: " + zip);

Type guard

boolean isZipSegment(Map<String,Object> loadSpec) {
  Object p = loadSpec.get("path");
  return p instanceof String && ((String) p).endsWith(".zip");
}

Try / catch

try {
  puller.getSegmentFiles(segment, outDir);
} catch (SegmentLoadingException e) {
  log.error(e, "corrupt zip for %s; discarding local copy", segment.getId());
  FileUtils.deleteQuietly(outDir);
}

Prevention

When it happens

Trigger: DataSegment with local loadSpec and zip-compressed segment file when CompressionUtils.unzip throws during getSegmentFiles.

Common situations: Truncated index.zip from an interrupted push; disk-full during extraction; copy tools that corrupted binary data (e.g. text-mode transfer); permission changes on the deep-storage directory.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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