{"record":{"id":"ea71aabd9f8bbb74","repo":"apache/druid","slug":"unable-to-load-from-local-directory-s","errorCode":null,"errorMessage":"Unable to load from local directory [%s]","messagePattern":"Unable to load from local directory \\[(.+?)\\]","errorType":"exception","errorClass":"SegmentLoadingException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/segment/loading/LocalDataSegmentPuller.java","lineNumber":156,"sourceCode":"            continue;\n          }\n\n          final File newFile = new File(dir, oldFile.getName());\n          final FileUtils.LinkOrCopyResult linkOrCopyResult = FileUtils.linkOrCopy(oldFile, newFile);\n          link = link && linkOrCopyResult == FileUtils.LinkOrCopyResult.LINK;\n          result.addFile(newFile);\n        }\n        log.info(\n            \"%s %d bytes from [%s] to [%s]\",\n            link ? \"Linked\" : \"Copied\",\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 load from local directory [%s]\", sourceFile.getAbsolutePath());\n      }\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) {","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/segment/loading/LocalDataSegmentPuller.java#L138-L174","documentation":"LocalDataSegmentPuller.getSegmentFiles throws SegmentLoadingException when it fails to extract a locally stored segment that is a .tgz/.tar.gz archive. The underlying IOException (missing file, permissions, corrupt archive, full disk) is wrapped with the source file path. This is the local-filesystem deep-storage loader, so it means the segment archive on disk could not be expanded into the target directory.","triggerScenarios":"DataSegment whose loadSpec type is 'local' and whose file name ends in .tgz/.tar.gz, when CompressionUtils.tarGz to the output dir throws IOException during getSegmentFiles.","commonSituations":"Manually copied or trimmed druid segment directories on historical nodes; segments corrupted by incomplete writes or disk-full; files moved without their archive; read-permission loss after user change; corrupting archives by editing deep-storage files by hand.","solutions":["Verify the source file exists and is readable by the Druid process user (ls -l on the path in the message).","Test archive integrity with `tar -tzf <file>`; re-ingest or re-replicate the segment if it is corrupt.","Check disk space and write permission on the output directory.","Remove/re-download the bad segment copy: disable the segment and let Druid re-replicate from another replica."],"exampleFix":"// before (manual copy skipped nested files)\ncp -r /mnt/old-deepstorage/druid/segments/wikipedia/2015/ /mnt/deepstorage/druid/segments/wikipedia/2015/\n// after (copy full segment dir, verify archive)\nrsync -a /mnt/old-deepstorage/druid/segments/wikipedia/2015/01/ /mnt/deepstorage/druid/segments/wikipedia/2015/01/\ntar -tzf /mnt/deepstorage/druid/segments/wikipedia/2015/01/2015-01-01T00:00:00.000Z_2015-01-02T00:00:00.000Z_day/0/index.zip","handlingStrategy":"try-catch","validationCode":"final File f = new File((String) segment.getLoadSpec().get(\"path\"));\nif (!f.isFile() || !f.canRead()) throw new IllegalStateException(\"segment source unreadable: \" + f);\nif (!f.getName().endsWith(\".tar.gz\") && !f.getName().endsWith(\".tgz\")) throw new IllegalStateException(\"not a tgz archive: \" + f);","typeGuard":"boolean isTgzSegment(Map<String,Object> loadSpec) {\n  Object p = loadSpec.get(\"path\");\n  return p instanceof String && ((String) p).matches(\".*\\\\.(tar\\\\.gz|tgz)$\");\n}","tryCatchPattern":"try {\n  puller.getSegmentFiles(segment, outDir);\n} catch (SegmentLoadingException e) {\n  log.error(e, \"failed to extract local segment %s; marking replica bad\", segment.getId());\n  // let Druid re-replicate from another replica\n}","preventionTips":["Never modify or partially copy files in Druid deep storage by hand; use rsync -a and verify with tar -tzf.","Monitor disk space on deep-storage and segment-cache volumes.","Keep at least 2 segment replicas so a corrupt copy can be replaced.","Run deep storage under a stable service user with consistent permissions."],"tags":["segment-loading","io","local-deep-storage","archive-extraction"],"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"}