apache/iceberg · error · NoSuchPlanTaskException
Could not find tasks for plan task
Error message
Could not find tasks for plan task %s
What it means
InMemoryPlanningState maps each plan-task key to its resulting List<FileScanTask>. fileScanTasksForPlanTask throws NoSuchPlanTaskException when the given plan-task key has no entry, i.e. tasks were never registered or were fetched under a wrong key.
Solutions
- Fetch task keys only from the plan status/response objects produced by the same planning session
- Wait until the plan status is COMPLETED before fetching file scan tasks
- Verify the exact plan-task key string, including sequence-number suffixes
- Re-run planning if the in-memory state was reset
Example fix
// before
List<FileScanTask> tasks = state.fileScanTasksForPlanTask(rawKey); // key may be wrong
// after
PlanStatus st = state.asyncPlanStatus(planId);
if (st == PlanStatus.COMPLETED) {
List<FileScanTask> tasks = state.fileScanTasksForPlanTask(planResponse.nextPlanTask());
} Defensive patterns
Strategy: try-catch
Validate before calling
if (planTaskKey == null || planTaskKey.isEmpty()) throw new IllegalArgumentException("plan task key required"); Try / catch
try {
tasks = planningState.fileScanTasksForPlanTask(taskKey);
} catch (NoSuchPlanTaskException e) {
tasks = List.of(); // or re-plan the scan
} Prevention
- Only use task keys emitted by the same planning session
- Fetch tasks only after the plan status is COMPLETED
- Avoid hand-building or truncating plan-task key strings
- Re-plan if the test server state was reset
When it happens
Trigger: Requesting file scan tasks for a plan-task key that was never produced by plan submission; using a truncated/malformed task key; querying tasks before the plan reached COMPLETED status; hitting a different server instance than the one that planned the scan.
Common situations: Test harness pagination logic using incorrect next-plan-task keys; clients reading task results from a stale or restarted in-memory server; mixing plan IDs and task keys.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot find plan with id
- Could not find plan ID
- Namespace does not exist
- View does not exist
- Can't handle
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/b283bd080bb3dd4f.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/rest/InMemoryPlanningState.java:115
existingStatus);
asyncPlanningStates.put(plan, PlanStatus.COMPLETED);
}
void markAsyncPlanFailed(String plan) {
PlanStatus existingStatus = asyncPlanningStates.get(plan);
Preconditions.checkArgument(existingStatus != null, "Cannot find plan %s", plan);
Preconditions.checkArgument(
existingStatus == PlanStatus.SUBMITTED,
"Cannot mark plan %s as completed as it is %s",
plan,
existingStatus);
asyncPlanningStates.put(plan, PlanStatus.FAILED);
}
List<FileScanTask> fileScanTasksForPlanTask(String planTaskKey) {
List<FileScanTask> tasks = planTaskToFileScanTasks.get(planTaskKey);
if (tasks == null) {
throw new NoSuchPlanTaskException("Could not find tasks for plan task %s", planTaskKey);
}
return tasks;
}
List<String> nextPlanTask(String planTaskKey) {
String nextPlanTask = planTaskToNext.get(planTaskKey);
if (nextPlanTask != null) {
return ImmutableList.of(nextPlanTask);
}
return ImmutableList.of();
}
/**
* Retrieves the initial set of file scan tasks for a plan. PlanIDs are assumed to be separated
* with hyphens where the last component indicates the sequencing of plan IDs.
*View on GitHub (pinned to 86d9c8fc54)