{"record":{"id":"2fc9a823ffa19636","repo":"apache/iceberg","slug":"failed-to-bind-to-expected-schema-skipping-run-2fc9a8","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/v4.0/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/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkBatchQueryScan.java#L187-L223","documentation":"During scan planning Spark may pass runtime (dynamic) filters down; SparkBatchQueryScan attempts to convert each Spark V2 predicate to an Iceberg expression and bind it to the expected schema. If binding fails with ValidationException, the filter cannot be applied safely on Iceberg's side, so it is logged and skipped — the query still runs, just without that runtime filter optimization.","triggerScenarios":"A Spark runtime filter (e.g. from a bloom filter or dynamic pruning) references a column or type not present/compatible with the scan's expectedSchema, causing Binder.bind to throw ValidationException.","commonSituations":"Runtime bloom filters built on partition or metadata columns absent from the projected schema; schema evolution making a runtime filter's type incompatible; case-sensitivity mismatches.","solutions":["No action strictly required — the filter is skipped and correctness is preserved.","Check the referenced expression against the table schema; align column names/types if you want the filter applied.","Verify case sensitivity settings (spark.sql.caseSensitive) match the filter's column casing."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// ensure the runtime filter column exists and type-compatible before relying on pushdown\nboolean columnInSchema = expectedSchema.columns().stream()\n    .anyMatch(c -> c.name().equalsIgnoreCase(filterColumn));","typeGuard":"boolean bindable = expr != null && expectedSchema.caseInsensitiveFindField(filterColumn) != null;","tryCatchPattern":"try { Binder.bind(expectedSchema.asStruct(), expr, caseSensitive()); } catch (ValidationException e) { /* skip filter, rely on post-scan evaluation */ }","preventionTips":["Keep runtime filter columns in the scan projection/schema.","Match spark.sql.caseSensitive with your column naming.","Don't rely on runtime filters for correctness — they are optional."],"tags":["spark","runtime-filter","schema","performance"],"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"}