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

  1. No correctness action needed — the filter is still applied by Spark after the scan.
  2. Inspect the logged exception message to identify the unsupported predicate.
  3. Simplify or rewrite the filter into supported comparison forms so it can be pushed down.
  4. 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

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


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)