apache/druid · error · IllegalStateException
Unrecognized state[ ] found.
Error message
Unrecognized state[%s] found.
What it means
SqlStatementState is derived from the underlying controller task's status; getSqlStatementState's switch exhaustively maps known states and throws ISE for anything unrecognized, guarding against future/unknown task states.
Solutions
- Upgrade all Druid nodes to a consistent version so state enums match
- Check the actual task state via the tasks API and re-poll
- If a transient/corrupt status, re-fetch the task status
Defensive patterns
Strategy: try-catch
Validate before calling
// only re-poll when the raw state is a known one
Set<String> known = Set.of("RUNNING","SUCCESS","FAILED","PENDING","CANCELED");
if (!known.contains(rawState)) { scheduleRepoll(); } Try / catch
try {
state = SqlStatementResourceHelper.getSqlStatementState(status);
} catch (ISE e) {
// unknown state (version skew); re-poll or upgrade cluster
} Prevention
- Keep broker and overlord/task node versions aligned
- Re-fetch task status on unexpected values
- Handle new states gracefully after upgrades
When it happens
Trigger: The MSQ controller task reports a state not in the enum mapping (e.g. a new state added in a newer Druid version while an older broker parses it, or a corrupt/foreign status payload).
Common situations: Rolling upgrades with mixed broker/task-node versions; querying a task whose status JSON contains an unexpected state value.
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
- Cannot mark the stage
- Cannot start the stage
- Work order not present for stage
- Worker[ ] cannot transistion from state[ ] to state[ ]…
- Broadcast input number out of range
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/77aaa3cd44960d27.
Report an issue: GitHub.
Appendix: source
Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/util/SqlStatementResourceHelper.java:142
{
TaskState state = taskStatusPlus.getStatusCode();
if (state == null) {
return SqlStatementState.ACCEPTED;
}
switch (state) {
case FAILED:
return SqlStatementState.FAILED;
case RUNNING:
if (TaskLocation.unknown().equals(taskStatusPlus.getLocation())) {
return SqlStatementState.ACCEPTED;
} else {
return SqlStatementState.RUNNING;
}
case SUCCESS:
return SqlStatementState.SUCCESS;
default:
throw new ISE("Unrecognized state[%s] found.", state);
}
}
/**
* Populates pages list from the {@link CounterSnapshotsTree}.
* <br>
* The number of pages changes with respect to the destination
* <ol>
* <li>{@link DataSourceMSQDestination} a single page is returned which adds all the counters of {@link SegmentGenerationProgressCounter.Snapshot}</li>
* <li>{@link TaskReportMSQDestination} a single page is returned which adds all the counters of {@link ChannelCounters}</li>
* <li>{@link DurableStorageMSQDestination} a page is returned for each partition, worker which has generated output rows. The pages are populated in the following order:
* <ul>
* <li>For each partition from 0 to N</li>
* <li>For each worker from 0 to M</li>
* <li>If num rows for that partition,worker combination is 0, create a page</li>
* so that we maintain the record ordering.
* </ul>
* </ol>View on GitHub (pinned to 9b90983fd2)