apache/iceberg · error · IllegalStateException
failureMessage(planId, response.errorResponse())
Error message
failureMessage(planId, response.errorResponse())
What it means
Thrown by RESTTableScan when a remotely planned scan reports planStatus=FAILED. The server-side scan planning job failed and the errorResponse details from the REST server are embedded in the message via failureMessage. The scan cannot produce tasks without a completed plan.
Solutions
- Read the embedded server errorResponse message in the exception for the root cause and fix the server-side condition
- Retry the scan; if persistent, fall back to a catalog that plans scans client-side
- Verify the table metadata/snapshot is valid and accessible to the REST planning service
- Check REST server logs for the failing planId
Example fix
try {
TableScan scan = table.newScan().planWithRemotePlanning(true);
scan.planFiles();
} catch (IllegalStateException e) {
// e.getMessage() contains the server errorResponse; fall back
scan = table.newScan().planWithRemotePlanning(false);
scan.planFiles();
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check supported endpoints before enabling remote planning boolean remotePlanning = supportedEndpoints.contains(Endpoint.V1_FETCH_TABLE_SCAN_PLAN);
Try / catch
try { scan.planFiles(); } catch (IllegalStateException e) {
if (e.getMessage().contains("Remote scan planning failed")) { /* fallback to client planning */ }
else throw e;
} Prevention
- Verify the REST server advertises the fetch-scan-plan endpoint before enabling async planning
- Keep client and server Iceberg REST spec versions aligned
- Monitor server-side planning health for large scans
When it happens
Trigger: Calling planFiles/planTableScan against a REST catalog that supports async scan planning (Endpoint.V1_FETCH_TABLE_SCAN_PLAN); the server returns a FetchScanPlanningResult with planStatus FAILED and a non-null errorResponse.
Common situations: Server-side planning failures: invalid snapshot references, table metadata unreadable by the planning service, server OOM or internal errors during large partitioned scans, incompatible scan filters the server cannot evaluate.
Related errors
- failureMessage(id, response.errorResponse())
- Remote scan planning cancelled for planId
- Remote scan planning for planId
- Invalid planStatus: for planId
- Service failed
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/d46e22d3f8d3d3ca.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/rest/RESTTableScan.java:222
PlanTableScanResponse.class,
headers,
ErrorHandlers.tableErrorHandler(),
stringStringMap -> {},
parserContext);
this.planId = response.planId();
PlanStatus planStatus = response.planStatus();
this.scanFileIO =
!response.credentials().isEmpty() ? scanFileIO(response.credentials()) : table().io();
switch (planStatus) {
case COMPLETED:
return scanTasksIterable(response.planTasks(), response.fileScanTasks());
case SUBMITTED:
Endpoint.check(supportedEndpoints, Endpoint.V1_FETCH_TABLE_SCAN_PLAN);
return fetchPlanningResult();
case FAILED:
throw new IllegalStateException(failureMessage(planId, response.errorResponse()));
default:
throw new IllegalStateException(
String.format("Invalid planStatus: %s for planId: %s", planStatus, planId));
}
}
private FileIO scanFileIO(List<Credential> storageCredentials) {
ImmutableMap.Builder<String, String> builder =
ImmutableMap.<String, String>builder().putAll(catalogProperties);
if (null != planId) {
builder.put(RESTCatalogProperties.REST_SCAN_PLAN_ID, planId);
}
Map<String, String> properties = builder.buildKeepingLast();
FileIO ioForScan =
CatalogUtil.loadFileIO(
catalogProperties.getOrDefault(CatalogProperties.FILE_IO_IMPL, DEFAULT_FILE_IO_IMPL),
properties,View on GitHub (pinned to 86d9c8fc54)