{"record":{"id":"dc012cceb6994e3d","repo":"apache/druid","slug":"unable-to-unzip-file-s","errorCode":null,"errorMessage":"Unable to unzip file [%s]","messagePattern":"Unable to unzip file \\[(.+?)\\]","errorType":"exception","errorClass":"SegmentLoadingException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/segment/loading/LocalDataSegmentPuller.java","lineNumber":175,"sourceCode":"      }\n    } else if (CompressionUtils.isZip(sourceFile.getName())) {\n      try {\n        final FileUtils.FileCopyResult result = CompressionUtils.unzip(\n            Files.asByteSource(sourceFile),\n            dir,\n            shouldRetryPredicate(),\n            false\n        );\n        log.info(\n            \"Unzipped %d bytes from [%s] to [%s]\",\n            result.size(),\n            sourceFile.getAbsolutePath(),\n            dir.getAbsolutePath()\n        );\n        return result;\n      }\n      catch (IOException e) {\n        throw new SegmentLoadingException(e, \"Unable to unzip file [%s]\", sourceFile.getAbsolutePath());\n      }\n    } else if (CompressionUtils.isGz(sourceFile.getName())) {\n      final File outFile = new File(dir, CompressionUtils.getGzBaseName(sourceFile.getName()));\n      final FileUtils.FileCopyResult result = CompressionUtils.gunzip(\n          Files.asByteSource(sourceFile),\n          outFile,\n          shouldRetryPredicate()\n      );\n      log.info(\n          \"Gunzipped %d bytes from [%s] to [%s]\",\n          result.size(),\n          sourceFile.getAbsolutePath(),\n          outFile.getAbsolutePath()\n      );\n      return result;\n    } else {\n      throw new SegmentLoadingException(\"Do not know how to handle source [%s]\", sourceFile.getAbsolutePath());\n    }","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/segment/loading/LocalDataSegmentPuller.java#L157-L193","documentation":"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.","triggerScenarios":"DataSegment with local loadSpec and zip-compressed segment file when CompressionUtils.unzip throws during getSegmentFiles.","commonSituations":"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.","solutions":["Check `unzip -t <segment index.zip>` to confirm corruption.","Verify free disk space on the Druid segment cache directory.","Re-push the segment (re-run the task or use the segments REST API to reset) or re-copy it from a healthy replica.","Ensure the Druid process has read access to the source zip and write access to the target dir."],"exampleFix":"// before: extracting a zip corrupted by scp without binary mode\nscp oldhost:/ds/druid/.../index.zip /ds/druid/.../index.zip\n// after: verify and re-copy preserving binary\nrsync -a --checksum oldhost:/ds/druid/.../index.zip /ds/druid/.../\nunzip -t /ds/druid/.../index.zip","handlingStrategy":"try-catch","validationCode":"final File zip = new File((String) segment.getLoadSpec().get(\"path\"));\nif (!zip.isFile() || zip.length() == 0 || !zip.canRead()) throw new IllegalStateException(\"index.zip missing or unreadable: \" + zip);","typeGuard":"boolean isZipSegment(Map<String,Object> loadSpec) {\n  Object p = loadSpec.get(\"path\");\n  return p instanceof String && ((String) p).endsWith(\".zip\");\n}","tryCatchPattern":"try {\n  puller.getSegmentFiles(segment, outDir);\n} catch (SegmentLoadingException e) {\n  log.error(e, \"corrupt zip for %s; discarding local copy\", segment.getId());\n  FileUtils.deleteQuietly(outDir);\n}","preventionTips":["Always copy segment files in binary mode (rsync/scp -p), never text mode.","Verify archive integrity (unzip -t) after manual deep-storage copies.","Ensure adequate free disk space for extraction before load.","Keep healthy replicas so corrupt copies can be re-downloaded."],"tags":["segment-loading","io","zip","corrupt-archive"],"backgroundTag":"file-read-failed","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"}