apache/iceberg · error · IllegalStateException

Remote scan planning cancelled for planId

Error message

Remote scan planning cancelled for planId: %s

What it means

Thrown when the polled remote scan planning result has planStatus=CANCELLED, meaning the scan plan was cancelled on the server (explicit cancel or server-side timeout/cleanup). The client must restart planning.

Solutions

  1. Retry the whole scan (planTableScan) to create a fresh planId
  2. Increase server-side planning deadline if plans are timing out server-side
  3. Check server logs for why the plan was cancelled
  4. Avoid cancelling by ensuring the client process waits rather than aborting mid-plan
Defensive patterns

Strategy: retry

Try / catch

try { scan.planFiles(); } catch (IllegalStateException e) {
  if (e.getMessage().contains("cancelled")) { /* recreate scan and retry */ }
  else throw e;
}

Prevention

When it happens

Trigger: fetchPlanningResult polls after the plan was submitted and the server responds CANCELLED for that planId.

Common situations: Server cancels plans exceeding its internal deadline; an operator or client cancelled the plan; server restarts losing plan state and reporting cancelled.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/fd3097da8a830869. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/rest/RESTTableScan.java:293

                FetchPlanningResultResponse response =
                    client.get(
                        resourcePaths.plan(tableIdentifier, id),
                        headers,
                        FetchPlanningResultResponse.class,
                        headers,
                        ErrorHandlers.planErrorHandler(),
                        parserContext);

                switch (response.planStatus()) {
                  case COMPLETED:
                    result.set(response);
                    break;
                  case SUBMITTED:
                    throw new NotCompleteException();
                  case FAILED:
                    throw new IllegalStateException(failureMessage(id, response.errorResponse()));
                  case CANCELLED:
                    throw new IllegalStateException(
                        String.format(
                            Locale.ROOT, "Remote scan planning cancelled for planId: %s", id));
                  default:
                    throw new IllegalStateException(
                        String.format(
                            Locale.ROOT,
                            "Invalid planStatus: %s for planId: %s",
                            response.planStatus(),
                            id));
                }
              });
    } catch (NotCompleteException e) {
      throw new RemotePlanTimeoutException(
          String.format(
              Locale.ROOT,
              "Remote scan planning for planId: %s did not complete within configured limits"
                  + " (timeout=%d ms, maxRetries=%d)",
              planId,

View on GitHub (pinned to 86d9c8fc54)