apache/druid · error · SegmentLoadingException

Unknown segment killer type

Error message

Unknown segment killer type[%s].  Known types are %s

What it means

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.

Solutions

  1. Load the extension matching the loadSpec type in druid.extensions.loadList and restart.
  2. Inspect the segment's loadSpec in the metadata store (druid_segments table) to confirm the 'type' value.
  3. Fix typo'd/null 'type' entries with a metadata update or re-push affected segments.
  4. Manually delete orphaned data files and drop the segment rows if the old backend is retired.

Example fix

// before: killers for 'local' only, segments typed 'hdfs'
# druid.extensions.loadList=["druid-lookups-cached-global"]
// after
# druid.extensions.loadList=["druid-lookups-cached-global","druid-hdfs-storage"]
Defensive patterns

Strategy: validation

Validate before calling

String type = (String) segment.getLoadSpec().get("type");
if (type == null || !registeredKillerTypes.contains(type)) {
  throw new IllegalStateException("no killer for loadSpec type " + type);
}

Type guard

boolean killable(DataSegment segment) {
  Object t = segment.getLoadSpec().get("type");
  return t instanceof String && knownTypes.contains(t);
}

Try / catch

try {
  killer.kill(segment);
} catch (SegmentLoadingException e) {
  log.error(e, "cannot kill segment %s: unsupported storage type %s", segment.getId(), segment.getLoadSpec().get("type"));
  // fail kill task so coordinator retries after extension is added
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at server/src/main/java/org/apache/druid/segment/loading/OmniDataSegmentKiller.java:91

  public void kill(DataSegment segment) throws SegmentLoadingException
  {
    DataSegmentKiller dataSegmentKiller = getKiller(segment);
    if (dataSegmentKiller != null) {
      dataSegmentKiller.kill(segment);
    }
  }

  @Nullable
  private DataSegmentKiller getKiller(DataSegment segment) throws SegmentLoadingException
  {
    if (segment.isTombstone()) {
      return null;
    }
    String type = MapUtils.getString(segment.getLoadSpec(), "type");
    Supplier<DataSegmentKiller> killer = killers.get(type);

    if (killer == null) {
      throw new SegmentLoadingException("Unknown segment killer type[%s].  Known types are %s", type, killers.keySet());
    }

    return killer.get();
  }

  @Override
  public void killAll()
  {
    throw new UnsupportedOperationException("not implemented");
  }

  @Override
  public void killRecursively(String relativePath) throws IOException
  {
    IOException firstFailure = null;
    for (Supplier<DataSegmentKiller> supplier : killers.values()) {
      try {
        supplier.get().killRecursively(relativePath);

View on GitHub (pinned to 9b90983fd2)