apache/iceberg · error · UnsupportedOperationException

Cannot filter timestamps using predicate:

Error message

Cannot filter timestamps using predicate: 

What it means

ScanSummary.timestampRange throws UnsupportedOperationException when it encounters a time-filter predicate it does not know how to convert into a timestamp range. Only a fixed set of comparison predicates (e.g. lt, lte, gt, gte, eq on the timestamp column) is supported.

Solutions

  1. Rewrite the time filter using only supported comparison predicates (>, >=, <, <=, =).
  2. Decompose NOT/IN expressions into equivalent comparisons before passing them.
  3. Catch UnsupportedOperationException and fall back to an unbounded or manually computed range.

Example fix

// before
Expressions.not(Expressions.greaterThan("made_current_at", startTs))
// after
Expressions.lessThanOrEqual("made_current_at", startTs)
Defensive patterns

Strategy: validation

Validate before calling

Set<Expression.Operation> supported = Set.of(LT, LT_EQ, GT, GT_EQ, EQ);
Expression op = timeFilter;
if (!supported.contains(op.op())) { throw new IllegalArgumentException("unsupported time filter: " + op.op()); }

Try / catch

try { Pair<Long,Long> range = ScanSummary.timestampRange(...); } catch (UnsupportedOperationException e) { /* rewrite predicate as comparisons */ }

Prevention

When it happens

Trigger: Passing expressions like not(), in, notIn, or compound/not-negation predicates on the timestamp metric to ScanSummary's time-based filtering.

Common situations: Building snapshot summaries with complex user-supplied filter expressions; using NOT or IN on timestamp filters expecting them to be handled.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/f8fed75fa6ea327d. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/ScanSummary.java:420

          if (value + 1 > minTimestamp) {
            minTimestamp = value + 1;
          }
          break;
        case GT_EQ:
          if (value > minTimestamp) {
            minTimestamp = value;
          }
          break;
        case EQ:
          if (value < maxTimestamp) {
            maxTimestamp = value;
          }
          if (value > minTimestamp) {
            minTimestamp = value;
          }
          break;
        default:
          throw new UnsupportedOperationException(
              "Cannot filter timestamps using predicate: " + pred);
      }
    }

    if (maxTimestamp < minTimestamp) {
      throw new IllegalArgumentException(
          "No timestamps can match filters: " + Joiner.on(", ").join(timeFilters));
    }

    return Pair.of(minTimestamp, maxTimestamp);
  }
}

View on GitHub (pinned to 86d9c8fc54)