{"record":{"id":"4b5a67f469b87d55","repo":"apache/iceberg","slug":"failed-to-check-if-can-be-pushed-down-4b5a67","errorCode":null,"errorMessage":"Failed to check if {} can be pushed down: {}","messagePattern":"Failed to check if (.+?) can be pushed down: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkScanBuilder.java","lineNumber":186,"sourceCode":"        Expression expr = SparkV2Filters.convert(predicate);\n\n        if (expr != null) {\n          // try binding the expression to ensure it can be pushed down\n          Binder.bind(schema.asStruct(), expr, caseSensitive);\n          expressions.add(expr);\n          pushableFilters.add(predicate);\n        }\n\n        if (expr == null\n            || unpartitioned()\n            || !ExpressionUtil.selectsPartitions(expr, table, caseSensitive)) {\n          postScanFilters.add(predicate);\n        } else {\n          LOG.info(\"Evaluating completely on Iceberg side: {}\", predicate);\n        }\n\n      } catch (Exception e) {\n        LOG.warn(\"Failed to check if {} can be pushed down: {}\", predicate, e.getMessage());\n        postScanFilters.add(predicate);\n      }\n    }\n\n    this.filterExpressions = expressions;\n    this.pushedPredicates = pushableFilters.toArray(new Predicate[0]);\n\n    return postScanFilters.toArray(new Predicate[0]);\n  }\n\n  private boolean unpartitioned() {\n    return table.specs().values().stream().noneMatch(PartitionSpec::isPartitioned);\n  }\n\n  @Override\n  public Predicate[] pushedPredicates() {\n    return pushedPredicates;\n  }","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkScanBuilder.java#L168-L204","documentation":"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.","triggerScenarios":"An unexpected exception while testing a predicate's pushability (e.g. lambda/wrapper exceptions, unsupported literal handling throwing at runtime) inside pushPredicates.","commonSituations":"Unusual predicate types or nested functions during DSv2 filter pushdown; connector/Spark version mismatches where a predicate shape is mishandled.","solutions":["No correctness action needed — the filter is still applied by Spark after the scan.","Inspect the logged exception message to identify the unsupported predicate.","Simplify or rewrite the filter into supported comparison forms so it can be pushed down.","Report/upgrade if the exception indicates a connector bug."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Iceberg already catches Exception and falls back to post-scan filtering;\n// no user-side catch needed","preventionTips":["Use simple comparison predicates you expect to be pushable.","Keep Spark and Iceberg connector versions aligned.","Treat reduced pushdown as a performance regression, not a correctness bug."],"tags":["spark","pushdown","filter","performance"],"backgroundTag":"api-error-response","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"}