{"record":{"id":"7733940d62bfdc84","repo":"apache/druid","slug":"unknown-segment-killer-type-s-known-types-are","errorCode":null,"errorMessage":"Unknown segment killer type[%s].  Known types are %s","messagePattern":"Unknown segment killer type\\[(.+?)\\]\\.  Known types are (.+?)","errorType":"exception","errorClass":"SegmentLoadingException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/segment/loading/OmniDataSegmentKiller.java","lineNumber":91,"sourceCode":"  public void kill(DataSegment segment) throws SegmentLoadingException\n  {\n    DataSegmentKiller dataSegmentKiller = getKiller(segment);\n    if (dataSegmentKiller != null) {\n      dataSegmentKiller.kill(segment);\n    }\n  }\n\n  @Nullable\n  private DataSegmentKiller getKiller(DataSegment segment) throws SegmentLoadingException\n  {\n    if (segment.isTombstone()) {\n      return null;\n    }\n    String type = MapUtils.getString(segment.getLoadSpec(), \"type\");\n    Supplier<DataSegmentKiller> killer = killers.get(type);\n\n    if (killer == null) {\n      throw new SegmentLoadingException(\"Unknown segment killer type[%s].  Known types are %s\", type, killers.keySet());\n    }\n\n    return killer.get();\n  }\n\n  @Override\n  public void killAll()\n  {\n    throw new UnsupportedOperationException(\"not implemented\");\n  }\n\n  @Override\n  public void killRecursively(String relativePath) throws IOException\n  {\n    IOException firstFailure = null;\n    for (Supplier<DataSegmentKiller> supplier : killers.values()) {\n      try {\n        supplier.get().killRecursively(relativePath);","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/segment/loading/OmniDataSegmentKiller.java#L73-L109","documentation":"OmniDataSegmentKiller.getKiller throws SegmentLoadingException when the segment's loadSpec 'type' has no registered DataSegmentKiller. The killer dispatcher needs a killer per deep-storage type to delete segment files; an unknown type means Druid cannot delete that segment's data.","triggerScenarios":"dataSegmentKiller(segment) called (via kill tasks or coordinator kill) with a loadSpec type not present in the killers map — extension not loaded, typo'd type, or null 'type' in loadSpec.","commonSituations":"Kill tasks failing after storage-type migration; metadata store contains segments from a storage backend whose extension is missing on the coordinator/overlord; hand-edited loadSpecs; upgrades that renamed a storage type.","solutions":["Load the extension matching the loadSpec type in druid.extensions.loadList and restart.","Inspect the segment's loadSpec in the metadata store (druid_segments table) to confirm the 'type' value.","Fix typo'd/null 'type' entries with a metadata update or re-push affected segments.","Manually delete orphaned data files and drop the segment rows if the old backend is retired."],"exampleFix":"// before: killers for 'local' only, segments typed 'hdfs'\n# druid.extensions.loadList=[\"druid-lookups-cached-global\"]\n// after\n# druid.extensions.loadList=[\"druid-lookups-cached-global\",\"druid-hdfs-storage\"]","handlingStrategy":"validation","validationCode":"String type = (String) segment.getLoadSpec().get(\"type\");\nif (type == null || !registeredKillerTypes.contains(type)) {\n  throw new IllegalStateException(\"no killer for loadSpec type \" + type);\n}","typeGuard":"boolean killable(DataSegment segment) {\n  Object t = segment.getLoadSpec().get(\"type\");\n  return t instanceof String && knownTypes.contains(t);\n}","tryCatchPattern":"try {\n  killer.kill(segment);\n} catch (SegmentLoadingException e) {\n  log.error(e, \"cannot kill segment %s: unsupported storage type %s\", segment.getId(), segment.getLoadSpec().get(\"type\"));\n  // fail kill task so coordinator retries after extension is added\n}","preventionTips":["Install the storage extension on overlord/coordinator nodes, not just historicals, so kill tasks can delete data.","When migrating deep-storage types, drain and kill old-type segments before removing the extension.","Audit the metadata store for null/typo'd loadSpec types after upgrades.","Keep druid.extensions.loadList identical across all Druid service roles."],"tags":["segment-kill","unsupported-type","configuration"],"backgroundTag":"invalid-enum-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}