{"record":{"id":"0066a5af36aae16f","repo":"apache/iceberg","slug":"unexpected-contentscantask-type-0066a5","errorCode":null,"errorMessage":"Unexpected ContentScanTask type: ","messagePattern":"Unexpected ContentScanTask type: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/EqualityConvertReader.java","lineNumber":126,"sourceCode":"  @Override\n  public void processElement(ReadCommand cmd, Context ctx, Collector<IndexCommand> out)\n      throws Exception {\n    ContentScanTask<?> task = cmd.task();\n    ContentFile<?> file = task.file();\n    try {\n      if (task instanceof FileScanTask dataTask) {\n        processDataFile(\n            dataTask,\n            cmd.mainSnapshotId(),\n            cmd.indexGeneration(),\n            cmd.dataSequenceNumber(),\n            cmd.staging(),\n            out);\n      } else if (task instanceof EqualityDeleteFileScanTask deleteTask) {\n        processDeleteFile(\n            deleteTask, cmd.mainSnapshotId(), cmd.indexGeneration(), cmd.dataSequenceNumber(), out);\n      } else {\n        throw new IllegalStateException(\n            \"Unexpected ContentScanTask type: \" + task.getClass().getName());\n      }\n    } catch (Exception e) {\n      LOG.error(\"Reader failed to process command for file={}\", file.location(), e);\n      ctx.output(TaskResultAggregator.ERROR_STREAM, e);\n      ctx.output(READER_ABORT_STREAM, DVPosition.ABORT);\n    }\n  }\n\n  private void processDataFile(\n      FileScanTask task,\n      Long mainSnapshotId,\n      Long indexGeneration,\n      long dataSequenceNumber,\n      boolean staging,\n      Collector<IndexCommand> out)\n      throws IOException {\n    ContentFile<?> file = task.file();","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/EqualityConvertReader.java#L108-L144","documentation":"Thrown by EqualityConvertReader.processElement when a ContentScanTask in a ReadCommand is neither a data-file task nor an EqualityDeleteFileScanTask. The reader dispatches on task type and fails with the concrete class name; the error is also emitted to the error stream and an ABORT is signaled on READER_ABORT_STREAM.","triggerScenarios":"A planner-emitted ReadCommand carries a ContentScanTask subtype the reader doesn't handle — typically after mixed operator versions (planner newer than reader), or custom pipeline modifications inserting new task types (e.g. other delete-scan tasks).","commonSituations":"Partial rolling upgrade of the Flink job with a savepoint from a different Iceberg version; hand-edited or forked planner code emitting tasks like DeleteFileIndex scan tasks the reader was not built for.","solutions":["Run all maintenance operators from the same Iceberg build; restart from a savepoint created by that same version.","Identify the unexpected class from the message and add a corresponding handler branch if it is a legitimate new task type from your fork.","Restore the stock planner/reader pipeline if custom modifications introduced the mismatch."],"exampleFix":"// before: planner from v1.9 emitting new task type, reader from v1.6\nStreamExecutionEnvironment env = ...; // operators built from two jars\n// after: build the whole job graph from one Iceberg version\nenv.fromSavepoint(sameVersionSavepoint); // all operators same jar/version","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// before sending a ReadCommand downstream\nif (!(cmd.scanTask() instanceof DataFileScanTask)\n    && !(cmd.scanTask() instanceof EqualityDeleteFileScanTask)) {\n  throw new IllegalArgumentException(\"Reader cannot handle task \" + cmd.scanTask().getClass());\n}","tryCatchPattern":"// Reader already reports failures via side outputs\nDataStream<?> readerOut = planner.getSideOutput(...).process(new EqualityConvertReader(...));\nreaderOut.getSideOutput(READER_ABORT_STREAM).process(new AbortHandler()); // react to ABORT instead of crashing the job","preventionTips":["Keep planner and reader in the same jar/version","Test custom task types against the reader dispatch before deploying","Avoid restoring savepoints across version mismatches","Watch READER_ABORT_STREAM to stop the job cleanly on this error"],"tags":["flink","type-mismatch","internal-protocol"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}