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
- Load the deep-storage extension matching the segment's loadSpec type (add it to druid.extensions.loadList).
- Verify the segment's loadSpec in the metadata store has a valid 'type' key.
- Check for typos in the loadSpec type; it must match a registered mover's type exactly.
- 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
- Load every deep-storage extension used by your cluster on all nodes that move segments.
- Validate loadSpec 'type' values after any deep-storage migration.
- Keep segment metadata loadSpecs consistent with deployed extensions.
- Log/alert on unknown types early during node startup by auditing segments against registered movers.
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
- e.getMessage()
- The gRPC query server requires either a Basic or Anonymous a
- Metric [%s] not whitelisted.
- Can't load TrustStore. Truststore path or password is not se
- druid.request.logging.transportUrl must be set when transpor
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/5363d26438face6e.
Report an issue: GitHub.