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

  1. Verify the runtime filter's column exists in the table schema with matching type and case
  2. Align spark.sql.sources.caseSensitive / column naming between join sides
  3. 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

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


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)