apache/iceberg · warning
Failed to bind to expected schema, skipping runtime filter
Error message
Failed to bind {} to expected schema, skipping runtime filter What it means
Spark passes runtime filters (dynamic pruning filters) to the scan; Iceberg converts them via SparkV2Filters and binds them to the expected scan schema. If binding fails (the filter's columns/structure don't fit the scan schema), the filter is skipped and a warning is logged — the query still runs, just with one fewer pushdown filter.
Solutions
- Verify the runtime filter's column exists in the table schema with matching type and case
- Align spark.sql.sources.caseSensitive / column naming between join sides
- Investigate why expectedSchema() differs from the filter schema (schema evolution, view expansion)
Example fix
-- before: filter column 'dt' not in schema (table evolved to 'event_date') SELECT ... FROM f JOIN d ON f.dt = d.dt -- after SELECT ... FROM f JOIN d ON f.event_date = d.dt
Defensive patterns
Strategy: validation
Validate before calling
Types.NestedField f = table.schema().caseInsensitiveFindField(filterColumn); boolean bindable = f != null && f.type().typeId() == filterType.typeId();
Try / catch
try { Binder.bind(expectedSchema.asStruct(), expr, caseSensitive); } catch (ValidationException e) { /* skip filter; verify join column exists in scan schema */ } Prevention
- Keep join/runtime-filter columns present and same-typed in both tables
- Watch for schema evolution that renames filter columns
- Match case sensitivity between Spark config and column names
When it happens
Trigger: A runtime (dynamic pruning / bloom) filter produced by Spark references a column not present in the scan's expected schema, or a name/type mismatch makes Binder.bind throw ValidationException.
Common situations: Case-sensitivity mismatches, star/schema evolution where the dimension table column no longer matches, or queries over views/row-tracked scans whose expected schema diverges from the filtered column.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Failed to bind to expected schema, skipping runtime filter
- Unsupported runtime filter
- Unsupported runtime filter
- Unsupported runtime filter
- Unsupported runtime filter
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ce019aa4c3d1c758.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkBatchQueryScan.java:205
return deleteFile.content() != FileContent.EQUALITY_DELETES;
}
return ContentFileUtil.isFileScoped(deleteFile);
}
// at this moment, Spark can only pass IN filters for a single attribute
// if there are multiple filter attributes, Spark will pass two separate IN filters
private Expression convertRuntimeFilters(Predicate[] predicates) {
Expression runtimeFilterExpr = Expressions.alwaysTrue();
for (Predicate predicate : predicates) {
Expression expr = SparkV2Filters.convert(predicate);
if (expr != null) {
try {
Binder.bind(expectedSchema().asStruct(), expr, caseSensitive());
runtimeFilterExpr = Expressions.and(runtimeFilterExpr, expr);
} catch (ValidationException e) {
LOG.warn("Failed to bind {} to expected schema, skipping runtime filter", expr, e);
}
} else {
LOG.warn("Unsupported runtime filter {}", predicate);
}
}
return runtimeFilterExpr;
}
@Override
public Statistics estimateStatistics() {
if (scan() == null) {
return estimateStatistics(null);
} else if (snapshotId != null) {
Snapshot snapshot = table().snapshot(snapshotId);
return estimateStatistics(snapshot);
View on GitHub (pinned to 86d9c8fc54)