apache/iceberg · warning
Unsupported runtime filter
Error message
Unsupported runtime filter {} What it means
SparkCopyOnWriteScan implements runtime filtering for copy-on-write deletes; when filter() receives a predicate that SparkV2Filters cannot convert to an Iceberg expression, it warns and ignores that predicate. Other convertible filters in the same call still apply, and scan correctness is unaffected.
Solutions
- No correctness action needed; the filter is simply not used to prune delete files.
- Confirm which predicate was unsupported and whether a supported equivalent exists.
- Upgrade the Iceberg Spark runtime for broader SparkV2Filters coverage.
Defensive patterns
Strategy: fallback
Type guard
if (SparkV2Filters.convert(predicate) == null) { /* unsupported for CoW delete planning */ } Prevention
- Restrict delete/merge conditions to supported comparisons when CoW performance matters.
- Upgrade connector versions for broader predicate conversion support.
- Monitor planning time; unpruned delete files signal skipped runtime filters.
When it happens
Trigger: Spark passes a runtime predicate with an unsupported function/type to SparkCopyOnWriteScan.filter during delete-file planning.
Common situations: Newer Spark runtime filter functions not yet mapped in SparkV2Filters; custom predicates applied during MERGE/DELETE planning on CoW tables.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unsupported runtime filter
- Failed to bind to expected schema, skipping runtime filter
- Unsupported runtime filter
- Unsupported runtime filter
- Failed to bind to expected schema, skipping runtime filter
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/50dc9a0a7ad5ad99.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkCopyOnWriteScan.java:141
// so filter files only if it is beneficial
if (filteredLocations == null || fileLocations.size() < filteredLocations.size()) {
this.filteredLocations = fileLocations;
List<FileScanTask> filteredTasks =
tasks().stream()
.filter(file -> fileLocations.contains(file.file().location()))
.collect(Collectors.toList());
LOG.info(
"{} of {} task(s) for table {} matched runtime file filter with {} location(s)",
filteredTasks.size(),
tasks().size(),
table().name(),
fileLocations.size());
resetTasks(filteredTasks);
}
} else {
LOG.warn("Unsupported runtime filter {}", predicate);
}
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SparkCopyOnWriteScan that = (SparkCopyOnWriteScan) o;
return table().name().equals(that.table().name())
&& readSchema().equals(that.readSchema()) // compare Spark schemas to ignore field ids
&& filterExpressions().toString().equals(that.filterExpressions().toString())View on GitHub (pinned to 86d9c8fc54)