apache/iceberg · warning
Failed to check if can be pushed down
Error message
Failed to check if {} can be pushed down: {} What it means
SparkScanBuilder.pushPredicates decides for each Spark Predicate whether it can be evaluated by Iceberg or must stay as a post-scan filter. The check itself threw a non-validation Exception, so Iceberg conservatively keeps the predicate on the Spark side and warns with the message. The query proceeds correctly; only pushdown (performance) may be reduced.
Solutions
- No correctness action needed — the filter is still applied by Spark after the scan.
- Inspect the logged exception message to identify the unsupported predicate.
- Simplify or rewrite the filter into supported comparison forms so it can be pushed down.
- Report/upgrade if the exception indicates a connector bug.
Defensive patterns
Strategy: fallback
Try / catch
// Iceberg already catches Exception and falls back to post-scan filtering; // no user-side catch needed
Prevention
- Use simple comparison predicates you expect to be pushable.
- Keep Spark and Iceberg connector versions aligned.
- Treat reduced pushdown as a performance regression, not a correctness bug.
When it happens
Trigger: An unexpected exception while testing a predicate's pushability (e.g. lambda/wrapper exceptions, unsupported literal handling throwing at runtime) inside pushPredicates.
Common situations: Unusual predicate types or nested functions during DSv2 filter pushdown; connector/Spark version mismatches where a predicate shape is mishandled.
Related errors
- Cannot convert non-reference to Parquet filter
- Cannot convert to Parquet filter
- Could not resolve using columns
- Couldn't set Arrow properties, which may impact read…
- Couldn't set Arrow properties, which may impact read…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4b5a67f469b87d55.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkScanBuilder.java:186
Expression expr = SparkV2Filters.convert(predicate);
if (expr != null) {
// try binding the expression to ensure it can be pushed down
Binder.bind(schema.asStruct(), expr, caseSensitive);
expressions.add(expr);
pushableFilters.add(predicate);
}
if (expr == null
|| unpartitioned()
|| !ExpressionUtil.selectsPartitions(expr, table, caseSensitive)) {
postScanFilters.add(predicate);
} else {
LOG.info("Evaluating completely on Iceberg side: {}", predicate);
}
} catch (Exception e) {
LOG.warn("Failed to check if {} can be pushed down: {}", predicate, e.getMessage());
postScanFilters.add(predicate);
}
}
this.filterExpressions = expressions;
this.pushedPredicates = pushableFilters.toArray(new Predicate[0]);
return postScanFilters.toArray(new Predicate[0]);
}
private boolean unpartitioned() {
return table.specs().values().stream().noneMatch(PartitionSpec::isPartitioned);
}
@Override
public Predicate[] pushedPredicates() {
return pushedPredicates;
}View on GitHub (pinned to 86d9c8fc54)