apache/druid · error · RE
statusCode[ ] and status[ ] must match
Error message
statusCode[%s] and status[%s] must match
What it means
TaskStatusPlus accepts either a numeric statusCode or a symbolic status enum; when both are supplied they must agree. A mismatch between the two representations indicates inconsistent task status data, so a RE is thrown from the constructor.
Solutions
- Send only one of statusCode or status in the JSON payload.
- Ensure both fields encode the same TaskState when both are present.
- Check the client/library version that produced the payload for stale serialization logic.
Example fix
// before
{"statusCode": "RUNNING", "status": "SUCCESS"}
// after
{"statusCode": "RUNNING"} Defensive patterns
Strategy: validation
Validate before calling
if (json.has("statusCode") && json.has("status") && !json.get("status").equals(TaskStatus.TaskState.fromCode(json.get("statusCode")))) { throw new IllegalArgumentException("statusCode and status conflict"); } Type guard
TaskStatus.TaskState resolveState(Integer statusCode, TaskStatus.TaskState status) {
if (statusCode != null && status == null) return TaskStatus.TaskState.fromCode(statusCode);
if (statusCode == null && status != null) return status;
if (statusCode != null && status != null && statusCode != status.getCode()) throw new IllegalArgumentException("statusCode/status mismatch");
return status;
} Try / catch
try { statusPlus = new TaskStatusPlus(id, ...statusCode, status, ...); } catch (RE e) { if (e.getMessage().contains("must match")) { log.error("Inconsistent task status payload for {}", id); } throw e; } Prevention
- Emit only one of statusCode/status in task-status JSON payloads
- Keep client serialization of task state in sync with server
- Validate task status responses before constructing TaskStatusPlus
When it happens
Trigger: Constructing a TaskStatusPlus with both statusCode and status set to different values, e.g. from a JSON payload where the numeric and string fields deserialized inconsistently.
Common situations: REST responses to /druid/indexer/v1/tasks where the JSON contains both fields with conflicting values; custom clients caching one field and updating the other.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- A local input source accepts only one of
- A local input source can set parameter
- A local input source requires one parameter of
- A local input source requires one property of
- A table definition must include a table spec.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/e275420893ba04ab.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/indexer/TaskStatusPlus.java:111
@JsonProperty("errorMsg") @Nullable String errorMsg
)
{
if (statusCode != null && statusCode.isComplete()) {
Preconditions.checkNotNull(duration, "duration");
}
this.id = Preconditions.checkNotNull(id, "id");
this.groupId = groupId;
this.type = type;
this.createdTime = Preconditions.checkNotNull(createdTime, "createdTime");
this.queueInsertionTime = Preconditions.checkNotNull(queueInsertionTime, "queueInsertionTime");
//checks for deserialization safety
if (statusCode != null && status == null) {
this.statusCode = statusCode;
} else if (statusCode == null && status != null) {
this.statusCode = status;
} else {
if (statusCode != null && status != null && statusCode != status) {
throw new RE("statusCode[%s] and status[%s] must match", statusCode, status);
}
this.statusCode = statusCode;
}
this.runnerTaskState = runnerTaskState;
this.duration = duration;
this.location = Preconditions.checkNotNull(location, "location");
this.dataSource = dataSource;
this.errorMsg = errorMsg;
}
@JsonProperty
public String getId()
{
return id;
}
@Nullable
@JsonPropertyView on GitHub (pinned to 9b90983fd2)