{"record":{"id":"344b20f0710ae589","repo":"apache/iceberg","slug":"too-many-matching-keys-more-than-d","errorCode":null,"errorMessage":"Too many matching keys: more than %d","messagePattern":"Too many matching keys: more than (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/ScanSummary.java","lineNumber":350,"sourceCode":"      this.maxSize = maxSize;\n      this.throwIfLimited = throwIfLimited;\n      this.map = Maps.newTreeMap(keyComparator);\n      this.keyComparator = keyComparator;\n    }\n\n    public void update(K key, Function<V, V> updateFunc) {\n      // if there is a cut and it comes before the given key, do nothing\n      if (cut != null && keyComparator.compare(cut, key) <= 0) {\n        return;\n      }\n\n      // call the update function and add the result to the map\n      map.put(key, updateFunc.apply(map.get(key)));\n\n      // enforce the size constraint and update the cut if some keys are excluded\n      while (map.size() > maxSize) {\n        if (throwIfLimited) {\n          throw new IllegalStateException(\n              String.format(Locale.ROOT, \"Too many matching keys: more than %d\", maxSize));\n        }\n        this.cut = map.lastKey();\n        map.remove(cut);\n      }\n    }\n\n    public Map<K, V> get() {\n      return ImmutableSortedMap.copyOfSorted(map);\n    }\n  }\n\n  static Expression joinFilters(List<Expression> expressions) {\n    Expression result = Expressions.alwaysTrue();\n    for (Expression expression : expressions) {\n      result = Expressions.and(result, expression);\n    }\n    return result;","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/ScanSummary.java#L332-L368","documentation":"ScanSummary's bounded size map (used for top-partition metrics) throws IllegalStateException when the number of distinct matching keys exceeds maxSize and the summary was configured with throwIfLimited=true, i.e. limiting results by dropping keys is not allowed.","triggerScenarios":"Computing ScanSummary partition metrics on a table with more distinct partition keys than the configured maxSize while throwIfLimited is set.","commonSituations":"High-cardinality partitions (e.g. hourly partitions over years) with a small summary limit; summarizing unpartitioned-turned-partitioned large tables.","solutions":["Increase the maxSize limit for the summary computation.","Construct the summary with throwIfLimited=false to truncate to the top keys instead of failing.","Narrow the scan (filter by partition/predicate) to reduce distinct matching keys."],"exampleFix":"// before\nnew ScanSummary.LimitedSizeMap<>(maxSize, true); // throws when exceeded\n// after\nnew ScanSummary.LimitedSizeMap<>(maxSize, false); // truncate to top keys","handlingStrategy":"try-catch","validationCode":"long distinctPartitions = estimateDistinctPartitions(table);\nif (distinctPartitions > maxSize) { /* raise maxSize or disable throwIfLimited */ }","typeGuard":null,"tryCatchPattern":"try { metrics = computeTopPartitionMetrics(...); } catch (IllegalStateException e) { /* increase maxSize or truncate instead of throwing */ }","preventionTips":["Size maxSize to expected partition cardinality","Use throwIfLimited=false for dashboards","Narrow scans with predicates on high-cardinality tables"],"tags":["iceberg","scan-summary","limit-exceeded","cardinality"],"backgroundTag":"value-out-of-range","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"}