apache/iceberg · error · IllegalArgumentException
Unsupported changelog scan task type: ${task.getClass().getN
Error message
Unsupported changelog scan task type: ${task.getClass().getName()} What it means
ChangelogRowReader throws IllegalArgumentException when a ChangelogScanTask instance is none of the three supported types (AddedRowsScanTask, DeletedRowsScanTask, DeletedDataFileScanTask). This indicates the scan planner produced a task type the row reader cannot handle, typically due to version skew.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/ChangelogRowReader.java:110
metadataRow.update(0, UTF8String.fromString(task.operation().name()));
metadataRow.update(1, task.changeOrdinal());
metadataRow.update(2, task.commitSnapshotId());
return metadataRow;
}
private CloseableIterable<InternalRow> openChangelogScanTask(ChangelogScanTask task) {
if (task instanceof AddedRowsScanTask) {
return openAddedRowsScanTask((AddedRowsScanTask) task);
} else if (task instanceof DeletedRowsScanTask) {
throw new UnsupportedOperationException("Deleted rows scan task is not supported yet");
} else if (task instanceof DeletedDataFileScanTask) {
return openDeletedDataFileScanTask((DeletedDataFileScanTask) task);
} else {
throw new IllegalArgumentException(
"Unsupported changelog scan task type: " + task.getClass().getName());
}
}
CloseableIterable<InternalRow> openAddedRowsScanTask(AddedRowsScanTask task) {
String filePath = task.file().location();
SparkDeleteFilter deletes = new SparkDeleteFilter(filePath, task.deletes(), counter(), true);
return deletes.filter(rows(task, deletes.requiredSchema()));
}
private CloseableIterable<InternalRow> openDeletedDataFileScanTask(DeletedDataFileScanTask task) {
String filePath = task.file().location();
SparkDeleteFilter deletes =
new SparkDeleteFilter(filePath, task.existingDeletes(), counter(), true);
return deletes.filter(rows(task, deletes.requiredSchema()));
}
private CloseableIterable<InternalRow> rows(ContentScanTask<DataFile> task, Schema readSchema) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Ensure a single consistent Iceberg Spark runtime version on the classpath
- Check for shaded/conflicting iceberg jars in the Spark session
- Verify no custom ChangelogScanTask implementations are registered
Example fix
// before
// mixed iceberg-spark-runtime 4.1 and iceberg-core 4.2 jars
// after
// single matching runtime
implementation("org.apache.iceberg:iceberg-spark-runtime-4.2_2.13:<same-version-everywhere>") Defensive patterns
Strategy: try-catch
Validate before calling
if (!(task instanceof AddedRowsScanTask || task instanceof DeletedRowsScanTask || task instanceof DeletedDataFileScanTask)) { throw before processing } Type guard
boolean isKnownChangelogTask(ChangelogScanTask t) { return t instanceof AddedRowsScanTask || t instanceof DeletedRowsScanTask || t instanceof DeletedDataFileScanTask; } Prevention
- Use exactly one Iceberg runtime version across the classpath
- Check for shaded duplicate iceberg jars
- Avoid custom ChangelogScanTask implementations with the stock reader
When it happens
Trigger: An unrecognized ChangelogScanTask subclass from a newer/older Iceberg runtime reaches openChangelogScanTask during changelog streaming.
Common situations: Mixing Iceberg jar versions (planner from one version, reader from another); custom scan task implementations injected via extensions.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Deleted rows scan task is not supported yet
- Unsupported changelog scan task type: ${task.getClass().getN
- Deleted rows scan task is not supported yet
- Deleted rows scan task is not supported yet
- Failed to close changelog scan: ${scan}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/83355308d806258b.
Report an issue: GitHub.