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

  1. Read the embedded server errorResponse message in the exception for the root cause and fix the server-side condition
  2. Retry the scan; if persistent, fall back to a catalog that plans scans client-side
  3. Verify the table metadata/snapshot is valid and accessible to the REST planning service
  4. 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

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


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)