{"record":{"id":"2686a33b0759fe09","repo":"apache/druid","slug":"unable-to-kill-segment-2686a3","errorCode":null,"errorMessage":"Unable to kill segment","messagePattern":"Unable to kill segment","errorType":"exception","errorClass":"SegmentLoadingException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/segment/loading/LocalDataSegmentKiller.java","lineNumber":85,"sourceCode":"        int maxDepth = 4; // if for some reason there's no datasSource directory, stop recursing somewhere reasonable\n        while (parentDir != null && --maxDepth >= 0) {\n          // parentDir.listFiles().length > 0 check not strictly necessary, because parentDir.delete() fails on\n          // nonempty directories. However, including it here is nice since it makes our intent very clear (only\n          // remove nonempty directories) and it prevents making delete syscalls that are doomed to failure.\n          if (parentDir.listFiles().length > 0\n              || !parentDir.delete()\n              || segment.getDataSource().equals(parentDir.getName())) {\n            break;\n          }\n\n          parentDir = parentDir.getParentFile();\n        }\n      } else if (path.exists()) {\n        throw new SegmentLoadingException(\"Unknown file type[%s]\", path);\n      }\n    }\n    catch (IOException e) {\n      throw new SegmentLoadingException(e, \"Unable to kill segment\");\n    }\n  }\n\n  @Override\n  public void killAll() throws IOException\n  {\n    log.info(\"Deleting all segments from directory[%s].\", storageDirectory.getAbsolutePath());\n    FileUtils.deleteDirectory(storageDirectory);\n  }\n\n  private File getPath(DataSegment segment)\n  {\n    return new File(MapUtils.getString(segment.getLoadSpec(), PATH_KEY));\n  }\n}\n","sourceCodeStart":67,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/segment/loading/LocalDataSegmentKiller.java#L67-L101","documentation":"The kill operation wraps any IOException encountered while deleting local segment files into a SegmentLoadingException with the message \"Unable to kill segment\", preserving the cause. It signals filesystem-level failure (permissions, missing parent directories, I/O errors) during segment cleanup.","triggerScenarios":"Calling kill or killAll when the local segment directory cannot be read/deleted — e.g. permission changes, read-only mounts, or concurrent deletion between the exists() check and delete.","commonSituations":"Running Druid as a user without ownership of the historical segment cache; NFS/EBS volume failures; administrators manually chmod'ing druid.storage dir.","solutions":["Check filesystem permissions on the segment cache directory (ls -la) and grant write access to the Druid process user.","Look at the wrapped IOException cause in the exception stack trace for the exact filesystem error.","Ensure the volume hosting the segment directory is mounted read-write and healthy, then retry the kill."],"exampleFix":"// before\n$ ls -ld /var/druid/segments  # root-owned\n// after\n$ chown -R druid:druid /var/druid/segments && retry kill via coordinator cleanup","handlingStrategy":"try-catch","validationCode":"File dir = new File(segmentDir);\nboolean canWrite = dir.exists() && dir.canWrite();","typeGuard":null,"tryCatchPattern":"try {\n  killer.kill(segment);\n} catch (SegmentLoadingException e) {\n  if (e.getCause() instanceof IOException) {\n    log.error(e.getCause(), \"Filesystem failure killing %s: check permissions/mount\", segment.getId());\n  }\n}","preventionTips":["Run the Druid process as the owner of the segment cache directory.","Monitor volumes hosting segment storage for read-only remounts."],"tags":["filesystem","permissions","segment-cleanup"],"backgroundTag":"file-write-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"}