{"record":{"id":"123e420ecba666fb","repo":"apache/iceberg","slug":"unsupported-runtime-filter","errorCode":null,"errorMessage":"Unsupported runtime filter {}","messagePattern":"Unsupported runtime filter (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkBatchQueryScan.java","lineNumber":208,"sourceCode":"    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\n    } else if (asOfTimestamp != null) {\n      long snapshotIdAsOfTime = SnapshotUtil.snapshotIdAsOfTime(table(), asOfTimestamp);\n      Snapshot snapshot = table().snapshot(snapshotIdAsOfTime);","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkBatchQueryScan.java#L190-L226","documentation":"A runtime filter predicate could not be converted to an Iceberg Expression by SparkV2Filters (returned null), so it cannot be pushed into the scan and is skipped with this warning. The query is unaffected except for losing that filter's pruning benefit.","triggerScenarios":"Spark passes a runtime filter type (e.g. certain IN/bloom-filter predicates) that SparkV2Filters.convert does not support.","commonSituations":"Dynamic partition pruning or runtime bloom filters on expressions Iceberg's converter doesn't handle, often with non-trivial join keys or specific Spark versions/features.","solutions":["Check the logged predicate and confirm it's a filter Iceberg supports converting","Ensure join/filter keys are simple columns to enable supported runtime filters","Ignore if performance is acceptable; it's a skipped optimization, not a failure"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use simple column equality/IN join keys so runtime filters are convertible","Treat as an optimization loss, not an error — verify query results are unaffected"],"tags":["spark","runtime-filter","pushdown","unsupported"],"backgroundTag":"unsupported-operation","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"}