apache/druid · error · SegmentLoadingException

Unknown loader type[%s]. Known types are %s

Error message

Unknown loader type[%s].  Known types are %s

What it means

OmniDataSegmentMover dispatches segment moves to a registered DataSegmentMover based on the 'type' key in the segment's loadSpec. If the type is missing or no mover is registered for it, it throws this SegmentLoadingException because it cannot move the segment.

Source

Thrown at server/src/main/java/org/apache/druid/segment/loading/OmniDataSegmentMover.java:62

      String type = entry.getKey();
      Provider<DataSegmentMover> provider = entry.getValue();
      this.movers.put(type, Suppliers.memoize(provider::get));
    }
  }

  @Override
  public DataSegment move(DataSegment segment, Map<String, Object> targetLoadSpec) throws SegmentLoadingException
  {
    return getMover(segment).move(segment, targetLoadSpec);
  }

  private DataSegmentMover getMover(DataSegment segment) throws SegmentLoadingException
  {
    String type = MapUtils.getString(segment.getLoadSpec(), "type");
    Supplier<DataSegmentMover> mover = movers.get(type);

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

    return mover.get();
  }

  @VisibleForTesting
  public Map<String, Supplier<DataSegmentMover>> getMovers()
  {
    return movers;
  }
}

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Load the deep-storage extension matching the segment's loadSpec type (add it to druid.extensions.loadList).
  2. Verify the segment's loadSpec in the metadata store has a valid 'type' key.
  3. Check for typos in the loadSpec type; it must match a registered mover's type exactly.
  4. If migrating deep storage, ensure the new backend's mover is registered before running moves.

Example fix

// before: extension missing
druid.extensions.loadList=["druid-kafka-indexing-service"]
// after: add the deep-storage extension matching segment loadSpec type
druid.extensions.loadList=["druid-kafka-indexing-service","druid-s3-extensions"]
Defensive patterns

Strategy: validation

Validate before calling

final Object type = segment.getLoadSpec().get("type");
if (type == null || !knownMoverTypes.contains(type.toString())) {
  throw new IllegalStateException("Segment " + segment.getId() + " has unsupported loadSpec type: " + type);
}

Type guard

static boolean hasKnownLoadSpecType(final DataSegment segment, final Set<String> knownTypes) {
  final Object type = segment.getLoadSpec().get("type");
  return type instanceof String s && knownTypes.contains(s);
}

Try / catch

try {
  omniMover.move(segment, target);
} catch (SegmentLoadingException e) {
  LOGGER.makeAlert(e, "Failed to move segment %s", segment.getId()).emit();
  // treat as unrecoverable for this node; rely on coordinator retry
}

Prevention

When it happens

Trigger: Calling move(dataSegment, ...) on a segment whose loadSpec lacks a 'type' entry, or whose loadSpec type (e.g. 's3_zip', 'azure', 'local') has no corresponding mover registered in the movers map.

Common situations: Deep-storage plugin not loaded on the coordinator/historical (e.g. druid-s3Extensions missing), a typo'd or custom loadSpec type in metadata, or segments written by another deep-storage backend being moved by a node that doesn't support that backend.

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/5363d26438face6e. Report an issue: GitHub.