{"record":{"id":"5c45eb2811de1b9d","repo":"apache/iceberg","slug":"unsupported-changelog-scan-task-type-task-getcl","errorCode":null,"errorMessage":"Unsupported changelog scan task type: ${task.getClass().getName()}","messagePattern":"Unsupported changelog scan task type: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/ChangelogRowReader.java","lineNumber":114,"sourceCode":"    metadataRow.update(0, UTF8String.fromString(task.operation().name()));\n    metadataRow.update(1, task.changeOrdinal());\n    metadataRow.update(2, task.commitSnapshotId());\n\n    return metadataRow;\n  }\n\n  private CloseableIterable<InternalRow> openChangelogScanTask(ChangelogScanTask task) {\n    if (task instanceof AddedRowsScanTask) {\n      return openAddedRowsScanTask((AddedRowsScanTask) task);\n\n    } else if (task instanceof DeletedRowsScanTask) {\n      throw new UnsupportedOperationException(\"Deleted rows scan task is not supported yet\");\n\n    } else if (task instanceof DeletedDataFileScanTask) {\n      return openDeletedDataFileScanTask((DeletedDataFileScanTask) task);\n\n    } else {\n      throw new IllegalArgumentException(\n          \"Unsupported changelog scan task type: \" + task.getClass().getName());\n    }\n  }\n\n  CloseableIterable<InternalRow> openAddedRowsScanTask(AddedRowsScanTask task) {\n    String filePath = task.file().location();\n    SparkDeleteFilter deletes = new SparkDeleteFilter(filePath, task.deletes(), counter(), true);\n    return deletes.filter(rows(task, deletes.requiredSchema()));\n  }\n\n  private CloseableIterable<InternalRow> openDeletedDataFileScanTask(DeletedDataFileScanTask task) {\n    String filePath = task.file().location();\n    SparkDeleteFilter deletes =\n        new SparkDeleteFilter(filePath, task.existingDeletes(), counter(), true);\n    return deletes.filter(rows(task, deletes.requiredSchema()));\n  }\n\n  private CloseableIterable<InternalRow> rows(ContentScanTask<DataFile> task, Schema readSchema) {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/ChangelogRowReader.java#L96-L132","documentation":"The final else branch of openChangelogScanTask throws IllegalArgumentException when the ChangelogScanTask instance matches none of the known subtypes. This guards against task types introduced by newer Iceberg versions that this reader does not recognize.","triggerScenarios":"openChangelogScanTask receives a ChangelogScanTask implementation that is not AddedRowsScanTask, DeletedRowsScanTask, or DeletedDataFileScanTask — e.g. a new task type from a newer core version mixed with an older Spark runtime.","commonSituations":"Version skew between iceberg-core/iceberg-spark jars on the classpath, or custom ChangelogScanTask implementations.","solutions":["Align all Iceberg jars (core, api, spark) to the same version to avoid unknown task types.","Check the class name in the message; search Iceberg for the task type and upgrade to a version that handles it.","Remove custom task implementations from the classpath if any."],"exampleFix":"// before: mixed iceberg-core 1.6 with iceberg-spark 1.5 jars\n// after: use a single managed version\nimplementation(\"org.apache.iceberg:iceberg-spark-3.5_2.12:1.6.0\")","handlingStrategy":"try-catch","validationCode":"Map<String,String> versions = classpathIcebergVersions(); // e.g. inspect jar manifests\nSet<String> distinct = new HashSet<>(versions.values());\nif (distinct.size() > 1) throw new IllegalStateException(\"Mixed Iceberg versions on classpath: \" + distinct);","typeGuard":"boolean isKnownChangelogTask(ChangelogScanTask task) {\n  return task instanceof AddedRowsScanTask\n      || task instanceof DeletedRowsScanTask\n      || task instanceof DeletedDataFileScanTask;\n}","tryCatchPattern":"try {\n  changelogDf.writeStream().start();\n} catch (StreamingQueryException e) {\n  if (e.getCause() instanceof IllegalArgumentException\n      && e.getCause().getMessage().startsWith(\"Unsupported changelog scan task type\")) {\n    // align Iceberg jar versions, then restart\n  } else { throw e; }\n}","preventionTips":["Use one managed Iceberg version for all modules in the dependency tree.","Avoid shading multiple Iceberg versions into the job classpath.","Upgrade reader runtime before enabling new writer features."],"tags":["spark","streaming","changelog","type-mismatch"],"backgroundTag":"invalid-enum-value","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"}