apache/druid · error · DruidException
Could not convert task[%s] to compatible object.
Error message
Could not convert task[%s] to compatible object.
What it means
LocalOverlordClient.convertTask() fails when Jackson cannot deserialize/serialize the task payload into the requested outputType (client-compatible object). On IOException it logs a warning and throws a defensive DruidException 'Could not convert task[%s] to compatible object.', indicating an internal invariant violation since task payloads should be convertible.
Source
Thrown at indexing-service/src/main/java/org/apache/druid/indexing/compact/LocalOverlordClient.java:190
{
if (taskPayload == null) {
return null;
} else if (!inputType.isInstance(taskPayload)) {
throw DruidException.defensive(
"Unknown type[%s] for compaction task. Expected type[%s].",
taskPayload.getClass().getSimpleName(), inputType.getSimpleName()
);
}
try {
return objectMapper.readValue(
objectMapper.writeValueAsBytes(taskPayload),
outputType
);
}
catch (IOException e) {
log.warn(e, "Could not convert task[%s] to client compatible object", taskPayload);
throw DruidException.defensive(
"Could not convert task[%s] to compatible object.",
taskPayload
);
}
}
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Ensure the task's type is registered in the injector's polymorphic ObjectMapper (register the task module/subtypes).
- Inspect the task payload in the metadata storage for corruption or schema drift.
- Align versions of indexing-service classes between writer and reader of the payload.
- File a bug if the payload is a standard Druid task type, since this is a defensive invariant failure.
Example fix
// before // Custom task class not registered -> convertTask throws DruidException // after // register the subtype so Jackson can map it objectMapper.registerSubtypes(MyCustomTask.class);
Defensive patterns
Strategy: try-catch
Validate before calling
// Before querying, confirm the task type is registered
if (!knownTaskTypes.contains(task.getType())) { throw new IllegalArgumentException("Unknown task type: " + task.getType()); } Try / catch
try { Task t = client.task(taskId); } catch (DruidException e) { if (e.getMessage().contains("Could not convert task")) { /* inspect payload / register subtype */ } } Prevention
- Register all custom task subtypes with the ObjectMapper
- Avoid hand-editing task payloads in metadata storage
- Keep overlord and client class versions aligned
When it happens
Trigger: task/taskPayload call encountering an IOException from objectMapper.readValue(taskJson, outputType) — e.g. task JSON incompatible with the expected type or missing modules.
Common situations: Custom task types not registered with the ObjectMapper (missing module/ subtype registration); corrupted or hand-edited task payloads in metadata storage; version skew between overlord and client task classes.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Failed to serialize TableDefn
- Ignore unparseable DruidService for [%s]: %s
- Object cannot be deserialized to a Moments Sketch:
- Failed to parse metric dimensions and types
- Couldn't deserialize authenticator userMap!
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/e0d70e4865a85ebc.
Report an issue: GitHub.