{"record":{"id":"fd3097da8a830869","repo":"apache/iceberg","slug":"remote-scan-planning-cancelled-for-planid-s","errorCode":null,"errorMessage":"Remote scan planning cancelled for planId: %s","messagePattern":"Remote scan planning cancelled for planId: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/rest/RESTTableScan.java","lineNumber":293,"sourceCode":"                FetchPlanningResultResponse response =\n                    client.get(\n                        resourcePaths.plan(tableIdentifier, id),\n                        headers,\n                        FetchPlanningResultResponse.class,\n                        headers,\n                        ErrorHandlers.planErrorHandler(),\n                        parserContext);\n\n                switch (response.planStatus()) {\n                  case COMPLETED:\n                    result.set(response);\n                    break;\n                  case SUBMITTED:\n                    throw new NotCompleteException();\n                  case FAILED:\n                    throw new IllegalStateException(failureMessage(id, response.errorResponse()));\n                  case CANCELLED:\n                    throw new IllegalStateException(\n                        String.format(\n                            Locale.ROOT, \"Remote scan planning cancelled for planId: %s\", id));\n                  default:\n                    throw new IllegalStateException(\n                        String.format(\n                            Locale.ROOT,\n                            \"Invalid planStatus: %s for planId: %s\",\n                            response.planStatus(),\n                            id));\n                }\n              });\n    } catch (NotCompleteException e) {\n      throw new RemotePlanTimeoutException(\n          String.format(\n              Locale.ROOT,\n              \"Remote scan planning for planId: %s did not complete within configured limits\"\n                  + \" (timeout=%d ms, maxRetries=%d)\",\n              planId,","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/RESTTableScan.java#L275-L311","documentation":"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.","triggerScenarios":"fetchPlanningResult polls after the plan was submitted and the server responds CANCELLED for that planId.","commonSituations":"Server cancels plans exceeding its internal deadline; an operator or client cancelled the plan; server restarts losing plan state and reporting cancelled.","solutions":["Retry the whole scan (planTableScan) to create a fresh planId","Increase server-side planning deadline if plans are timing out server-side","Check server logs for why the plan was cancelled","Avoid cancelling by ensuring the client process waits rather than aborting mid-plan"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { scan.planFiles(); } catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"cancelled\")) { /* recreate scan and retry */ }\n  else throw e;\n}","preventionTips":["Don't cancel/close scans mid-planning on the client side","Set generous server-side planning deadlines","Retry idempotently — each attempt creates a fresh planId"],"tags":["rest-catalog","scan-planning","cancelled","async"],"backgroundTag":"invalid-state-transition","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}