{"record":{"id":"ce019aa4c3d1c758","repo":"apache/iceberg","slug":"failed-to-bind-to-expected-schema-skipping-run","errorCode":null,"errorMessage":"Failed to bind {} to expected schema, skipping runtime filter","messagePattern":"Failed to bind (.+?) to expected schema, skipping runtime filter","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkBatchQueryScan.java","lineNumber":205,"sourceCode":"      return deleteFile.content() != FileContent.EQUALITY_DELETES;\n    }\n\n    return ContentFileUtil.isFileScoped(deleteFile);\n  }\n\n  // at this moment, Spark can only pass IN filters for a single attribute\n  // if there are multiple filter attributes, Spark will pass two separate IN filters\n  private Expression convertRuntimeFilters(Predicate[] predicates) {\n    Expression runtimeFilterExpr = Expressions.alwaysTrue();\n\n    for (Predicate predicate : predicates) {\n      Expression expr = SparkV2Filters.convert(predicate);\n      if (expr != null) {\n        try {\n          Binder.bind(expectedSchema().asStruct(), expr, caseSensitive());\n          runtimeFilterExpr = Expressions.and(runtimeFilterExpr, expr);\n        } catch (ValidationException e) {\n          LOG.warn(\"Failed to bind {} to expected schema, skipping runtime filter\", expr, e);\n        }\n      } else {\n        LOG.warn(\"Unsupported runtime filter {}\", predicate);\n      }\n    }\n\n    return runtimeFilterExpr;\n  }\n\n  @Override\n  public Statistics estimateStatistics() {\n    if (scan() == null) {\n      return estimateStatistics(null);\n\n    } else if (snapshotId != null) {\n      Snapshot snapshot = table().snapshot(snapshotId);\n      return estimateStatistics(snapshot);\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkBatchQueryScan.java#L187-L223","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"-- before: filter column 'dt' not in schema (table evolved to 'event_date')\nSELECT ... FROM f JOIN d ON f.dt = d.dt\n-- after\nSELECT ... FROM f JOIN d ON f.event_date = d.dt","handlingStrategy":"validation","validationCode":"Types.NestedField f = table.schema().caseInsensitiveFindField(filterColumn); boolean bindable = f != null && f.type().typeId() == filterType.typeId();","typeGuard":null,"tryCatchPattern":"try { Binder.bind(expectedSchema.asStruct(), expr, caseSensitive); } catch (ValidationException e) { /* skip filter; verify join column exists in scan schema */ }","preventionTips":["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"],"tags":["spark","runtime-filter","pushdown","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}