All findings · Lucene finding · LFV-983 · gettopdims-dim-queue-presized-by-topndims

SortedSetDocValues and taxonomy facets size the getTopDims dimension queue from topNDims, so getTopDims(Integer.MAX_VALUE, n) throws where getAllDims(n) returns every dim

On SortedSetDocValues and taxonomy facets, getTopDims(Integer.MAX_VALUE, 10) throws IllegalArgumentException even with only 2 dims, because the dimension queue is sized from the requested count before any dim is seen; getAllDims(10) returns both dims. Large legal values waste memory: getTopDims(1 << 24, 10) allocates 64 MiB for 2 dims.

Summary

Priority
Low, rank 644GetTopDims(Integer.MAX_VALUE, n) on SSDV and taxonomy facets throws a clear IllegalArgumentException and large values only waste memory, the same loud MAX_VALUE idiom as LFV-994 on a less-used facet call, so it follows that row.
Impact
crash
Since
9.2.0 (2022, when getTopDims was added)introduced 2022-03-28 · about 4 years
Affected
9.2.0 to 10.6.0 and main (10 affected version points run, the releases in between by reading); 9.1.0 has no getTopDims
Status
documented
Found by
AI tools: a numeric-limits probe, then a differential harness

AI-assisted page: this finding was first signalled by code reading or testing and then checked with AI tools; the checks it went through, and what each found, are under Prior reports, history and checks. Not yet triaged by a human. Snapshot of 2026-11-06.

The finding in 30 seconds

The optimized getTopDims of SortedSetDocValues and taxonomy facets sizes its dimension queue by the topNDims you pass, not by how many dims exist, and Lucene's priority queue refuses 2,147,483,631 slots or more.

Background: facet dims, getAllDims and getTopDims

  1. A facet dim (dimension) is a facet category such as author or year; each dim has labels with counts. SortedSetDocValues (SSDV) facets keep the labels in a doc-values field, taxonomy facets in a side index. Both implement the Facets API.
  2. getAllDims(n) returns every dim that had hits, each with its top n labels. getTopDims(topNDims, n) returns only the topNDims dims with the highest counts; its javadoc says the result should be getAllDims(n) cut to the first topNDims.
  3. Lucene's PriorityQueue allocates its whole array, maxSize + 1 slots, when it is created, and refuses sizes of 2,147,483,631 (ArrayUtil.MAX_ARRAY_LENGTH) or more.
Summary card of the bug: one document with the SortedSetDocValues facet labels a = x and b = y. Expected for getTopDims(Integer.MAX_VALUE, 10): a (1) and b (1), as getAllDims(10) returns. Actual: IllegalArgumentException "maxSize must be >= 0 and < 2147483631; got: 2147483647", in all five SortedSetDocValues and taxonomy classes. Why: both overrides build the dimension queue with PriorityQueue.usingComparator(topNDims, ...) before they visit any dim; PriorityQueue allocates maxSize + 1 slots up front and rejects sizes of 2,147,483,631 or more, while the default Facets#getTopDims caps with Math.min(topNDims, allResults.size()). Below the limit, topNDims = 2^24 returns both dims but allocates 67,110,600 bytes. The fix caps the queue at the label count (taxonomy: the ordinal count).
One document, 2 dims: getAllDims(10) returns a and b, but getTopDims(Integer.MAX_VALUE, 10) asks PriorityQueue for 2,147,483,647 slots before it looks at a dim and throws; capping the queue returns a and b. Select the still to open it at full size. Generated with AI, checked against the code.

The finding, step by step

  1. Index one document with two SortedSetDocValues facet labels, a/x and b/y (default FacetsConfig), and count all hits with SortedSetDocValuesFacetCounts. getAllDims(10) returns 2 dims, a and b.
  2. Ask for every dim with getTopDims(Integer.MAX_VALUE, 10). You expect a and b: the javadoc says the result should be getAllDims cut to the first topNDims, and the default Facets#getTopDims returns exactly that.
  3. You get IllegalArgumentException: maxSize must be >= 0 and < 2147483631; got: 2147483647, with assertions on and off. All five SortedSetDocValues and taxonomy count classes fail the same way.
  4. Why: before it visits any dim, the optimized getTopDims creates a priority queue with room for topNDims dims (AbstractSortedSetDocValueFacetCounts.java:154, TaxonomyFacets.java:611). Lucene's PriorityQueue allocates all topNDims + 1 slots up front and refuses 2,147,483,631 or more. The default getTopDims caps with Math.min; these overrides do not.
  5. Below that limit the call works but still reserves the slots: getTopDims(1 << 24, 10) on the same 2 dims allocates 67,110,600 bytes, against 1,744 bytes for getTopDims(2, 10).

Who is affected

Code that passes Integer.MAX_VALUE (or any topNDims from 2,147,483,631) to getTopDims on SortedSetDocValues or taxonomy facets to mean "all dims": every such call throws once anything was counted (the concurrent SortedSetDocValues class even when nothing was), at any index size, since 9.2.0. Large legal values reserve topNDims + 1 slots per call: 64 MiB at 2^24 on the tested JVM.

Mechanism, terms and numbers647 words

Facets#getTopDims(topNDims, topNChildren) is documented to return the same as getAllDims(topNChildren) cut to its first topNDims dims, and the default implementation does exactly that, capped with Math.min(topNDims, allResults.size()) (Facets.java:61-62, :69-72). The faster overrides used by SortedSetDocValues facets (AbstractSortedSetDocValueFacetCounts.java:153-157) and taxonomy facets (TaxonomyFacets.java:610-614) instead create PriorityQueue.usingComparator(topNDims, ...) before they look at any dim. Lucene's PriorityQueue allocates topNDims + 1 slots up front and refuses 2,147,483,631 or more.

So getTopDims(Integer.MAX_VALUE, 10) throws IllegalArgumentException on an index with 2 dims in SortedSetDocValuesFacetCounts, ConcurrentSortedSetDocValuesFacetCounts, FastTaxonomyFacetCounts, TaxonomyFacetIntAssociations and TaxonomyFacetFloatAssociations, while getAllDims(10) and the default getTopDims return both dims. Below the limit results are right but each call reserves the slots: about 64 MiB at 2^24 for 2 dims. Default configuration, any index size, assertions on and off, once a hit was counted (ConcurrentSortedSetDocValuesFacetCounts throws even for a query that matches nothing); every release since getTopDims was added in 9.2.0, through 10.6.0 and main. The fix is one Math.min per site.

The mechanism (main 645d4fe14a20)

  1. Contract. Facets#getTopDims (Facets.java:59-68): "Results should be the same as calling getAllDims and then only using the first topNDims. [...] Sub-classes may want to override this implementation with a more efficient one if they are able." The default body is allResults.subList(0, Math.min(topNDims, allResults.size())) (:69-72). validateTopN rejects only topN <= 0 (:80-84). The elided sentence asks that dims be configured as requiring dim counts so that counts are accurate (:62-64); neither override reads that setting before it sizes the queue.
  2. SSDV override. AbstractSortedSetDocValueFacetCounts.getTopDims (:143) validates both arguments (:144-145), returns an empty list when hasCounts() is false (:147-149; never for ConcurrentSortedSetDocValuesFacetCounts, whose hasCounts() always returns true, ConcurrentSortedSetDocValuesFacetCounts.java:80-84), then creates PriorityQueue.usingComparator(topNDims, ...) (:153-157; the throw frame is :154). Only then does it iterate state.getDims() (:162), adding a dim while pq.size() < topNDims (:201-202). SortedSetDocValuesFacetCounts and ConcurrentSortedSetDocValuesFacetCounts inherit it.
  3. Taxonomy override. TaxonomyFacets.getTopDims (:595) checks topNDims <= 0 || topNChildren <= 0 (:596-598), returns empty while its counters are uninitialized, i.e. no segment with hits was counted (:600-602), then creates PriorityQueue.usingComparator(topNDims, ...) (:610-614; throw frame :611) before it walks the root's children (:620). FastTaxonomyFacetCounts, TaxonomyFacetIntAssociations and TaxonomyFacetFloatAssociations inherit it.
  4. The queue. The PriorityQueue constructor throws IllegalArgumentException for maxSize >= ArrayUtil.MAX_ARRAY_LENGTH, commented "Throw exception to prevent confusing OOME" (PriorityQueue.java:121-125), and otherwise allocates new Object[maxSize + 1] (:129, :134). MAX_ARRAY_LENGTH is Integer.MAX_VALUE - NUM_BYTES_ARRAY_HEADER (ArrayUtil.java:33-34), 2,147,483,631 on this JVM. The class javadoc says it pre-allocates (:34); it is @lucene.internal (:39).
  5. The cap exists next door. The taxonomy child queue of the same class is new TopOrdAndIntQueue(Math.min(taxoReader.getSize(), topN)) (TaxonomyFacets.java:250-251). Only these two classes override getTopDims; every other Facets implementation inherits the capped default.

The numbers (main; one document with the labels a/x and b/y, as SortedSetDocValues facets, taxonomy facets and association fields; -ea and -da identical)

classgetTopDims(Integer.MAX_VALUE, 10)bytes at topNDims 2bytes at 2^24with the fix, 2^24
SortedSetDocValuesFacetCountsIllegalArgumentException1,74467,110,6001,744
ConcurrentSortedSetDocValuesFacetCountsIllegalArgumentException1,74467,110,6001,744
default getTopDims over SSDV countsa, b1,5041,504-
FastTaxonomyFacetCountsIllegalArgumentException1,40067,110,2561,408
TaxonomyFacetIntAssociationsIllegalArgumentException1,40067,110,2561,408
TaxonomyFacetFloatAssociations (association-value and values-source constructors)IllegalArgumentException1,46467,110,3201,472
default getTopDims over taxonomy countsa, b1,0721,072-

Bytes: what one call allocates on the calling thread (thread allocation counter), the minimum of 5 calls after 20 warm-up rounds, on this JVM (compressed references on). With the fix, Integer.MAX_VALUE returns a and b in all five classes and allocates the same as 2^24. getTopDims(2147483631, 10) throws the same way. An independent reproducer got an OutOfMemoryError for getTopDims(1 << 28, 5) with a 512 MB heap; an earlier probe measured 381 MiB at 10^8.

Exposure and likelihood310 words
  • Who is hit. Callers of getTopDims(topNDims, n) on SortedSetDocValuesFacetCounts, ConcurrentSortedSetDocValuesFacetCounts, FastTaxonomyFacetCounts, TaxonomyFacetIntAssociations or TaxonomyFacetFloatAssociations with Integer.MAX_VALUE, or any topNDims from 2,147,483,631 up. For a query that matches no document, SortedSetDocValuesFacetCounts and the taxonomy classes return an empty list before they build the queue (AbstractSortedSetDocValueFacetCounts.java:147-149, TaxonomyFacets.java:600-602); ConcurrentSortedSetDocValuesFacetCounts reports counts unconditionally (ConcurrentSortedSetDocValuesFacetCounts.java:80-84), so it throws even then, where its getAllDims(10) returns an empty list (executed). Code written against an implementation that keeps the capped default getTopDims (range, long-value and string-value counts inherit it; the default itself was executed through a wrapper over the SortedSetDocValues and taxonomy counts, not through those classes) meets it on the first call.
  • Large but legal topNDims. Values such as 2^24 used as "all" return correct results but reserve topNDims + 1 slots per call however few dims exist: about 64 MiB at 2^24 on the tested JVM (executed on every release point from 9.2.0 to main), 381 MiB at 10^8; an independent reproducer got an OutOfMemoryError at 2^28 with a 512 MB heap.
  • Default vs opt-in. Default FacetsConfig, codec and IndexSearcher; no setting is needed. Facets is @lucene.experimental; getTopDims dates from 9.2.0. The trigger is the topNDims value.
  • Who is not. getAllDims(n), the obvious call for all dims, works (on SSDV keep n bounded too: getAllDims(Integer.MAX_VALUE) hits the child-queue bug LFV-994). Ordinary topNDims values give correct results.
  • Severity. Loud: an exception for that call; no wrong results, nothing written to the index.
  • How likely. Rare: getAllDims is the natural call for "all dims", only values from 2,147,483,631 throw, and no public report was found. But Integer.MAX_VALUE is the usual Java "no limit" value, and Yuting Gan, who wrote getTopDims, said on #843, a range-facet getTopChildren change, that users who want all children can specify a large top-n; for dims that is an analogy.

Minimal repro

One JUnit class, one method, one document with 2 dims, default FacetsConfig; besides Lucene's test framework it uses only public API. It fails with assertions on and off, on main and on 10.6.0, and is also the suggested regression test.

TestGetTopDimsAllDims.java (JUnit, package org.apache.lucene.facet.sortedset)61 lines
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.lucene.facet.sortedset;

import java.util.List;
import org.apache.lucene.document.Document;
import org.apache.lucene.facet.FacetResult;
import org.apache.lucene.facet.Facets;
import org.apache.lucene.facet.FacetsCollector;
import org.apache.lucene.facet.FacetsCollectorManager;
import org.apache.lucene.facet.FacetsConfig;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.store.ByteBuffersDirectory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.tests.util.LuceneTestCase;

public class TestGetTopDimsAllDims extends LuceneTestCase {

  public void testGetTopDimsMaxValueReturnsAllDims() throws Exception {
    FacetsConfig config = new FacetsConfig();
    try (Directory dir = new ByteBuffersDirectory();
        IndexWriter w = new IndexWriter(dir, new IndexWriterConfig())) {
      Document doc = new Document();
      doc.add(new SortedSetDocValuesFacetField("a", "x"));
      doc.add(new SortedSetDocValuesFacetField("b", "y"));
      w.addDocument(config.build(doc));
      try (DirectoryReader reader = DirectoryReader.open(w)) {
        FacetsCollector fc =
            new IndexSearcher(reader).search(new MatchAllDocsQuery(), new FacetsCollectorManager());
        Facets facets =
            new SortedSetDocValuesFacetCounts(
                new DefaultSortedSetDocValuesReaderState(reader, config), fc);
        List<FacetResult> allDims = facets.getAllDims(10);
        try {
          assertEquals(allDims, facets.getTopDims(Integer.MAX_VALUE, 10));
        } catch (IllegalArgumentException e) {
          // expected: the 2 dims of getAllDims(10); actual: IllegalArgumentException from the queue
          throw new AssertionError("expected getAllDims(10) = " + allDims + ", but: " + e, e);
        }
      }
    }
  }
}
Command
cp $REPRO/TestGetTopDimsAllDims.java $LUCENE/lucene/facet/src/test/org/apache/lucene/facet/sortedset/
cd $LUCENE && ./gradlew :lucene:facet:test --tests org.apache.lucene.facet.sortedset.TestGetTopDimsAllDims -Ptests.seed=DEADBEEF -Ptests.asserts=true
# assertions off: -Ptests.asserts=false (same failure)
Expected
getTopDims(Integer.MAX_VALUE, 10) returns the 2 dims of getAllDims(10): a (value 1, child x (1)) and b (value 1, child y (1)).
Observed
IllegalArgumentException: maxSize must be >= 0 and < 2147483631; got: 2147483647 from AbstractSortedSetDocValueFacetCounts.java:154, with assertions on and off.

All files of this repro: repro/LFV-983/

More files, environment, full output291 words

The test indexes one document with SortedSetDocValuesFacetField("a", "x") and SortedSetDocValuesFacetField("b", "y"), counts MatchAllDocsQuery with SortedSetDocValuesFacetCounts, and asserts that getTopDims(Integer.MAX_VALUE, 10) equals getAllDims(10). Single thread, deterministic: the same failure for seeds DEADBEEF and 5EED0983; it fails with assertions on and off, on main and on the 10.6.0 release jars.

  • The IllegalArgumentException is caught once and rethrown as an AssertionError that states expected against actual (the exception stays the cause); a plain assertEquals fails too.
  • It covers the SortedSetDocValues site. The taxonomy site is the same expression; the probe and the earlier checks executed it in all three taxonomy classes. If you fix both sites in one PR, a taxonomy twin of this method (FastTaxonomyFacetCounts over FacetField("a", "x") and FacetField("b", "y")) covers the second.
  • Style: new MatchAllDocsQuery() is deprecated on main and in 10.6.0. The runs used the constructor; it does not affect the failure.
  • Set -Ptests.asserts explicitly: with a fixed seed and no value, Lucene's build picks the assertion mode from the seed.

Environment

lucenemain 645d4fe14a20 (11.0.0-SNAPSHOT); the 10.6.0 release fails too, as does every release run back to 9.2.0 (the releases in between by reading); 9.1.0 has no getTopDims
jdkOpenJDK 25.0.3
osLinux aarch64

Observed output

TestGetTopDimsAllDims > testGetTopDimsMaxValueReturnsAllDims FAILED
    java.lang.AssertionError: expected getAllDims(10) = [dim=a path=[] value=1 childCount=1
      x (1)
    , dim=b path=[] value=1 childCount=1
      y (1)
    ], but: java.lang.IllegalArgumentException: maxSize must be >= 0 and < 2147483631; got: 2147483647
        at __randomizedtesting.SeedInfo.seed([DEADBEEF:96CD7C7B56D70AB5]:0)
        at org.apache.lucene.facet.sortedset.TestGetTopDimsAllDims.testGetTopDimsMaxValueReturnsAllDims(TestGetTopDimsAllDims.java:56)

        Caused by:
        java.lang.IllegalArgumentException: maxSize must be >= 0 and < 2147483631; got: 2147483647
            at org.apache.lucene.core@11.0.0-SNAPSHOT/org.apache.lucene.util.PriorityQueue.<init>(PriorityQueue.java:123)
            at org.apache.lucene.core@11.0.0-SNAPSHOT/org.apache.lucene.util.PriorityQueue.<init>(PriorityQueue.java:80)
            at org.apache.lucene.core@11.0.0-SNAPSHOT/org.apache.lucene.util.PriorityQueue.usingComparator(PriorityQueue.java:63)
            at org.apache.lucene.facet.sortedset.AbstractSortedSetDocValueFacetCounts.getTopDims(AbstractSortedSetDocValueFacetCounts.java:154)
            at org.apache.lucene.facet.sortedset.SortedSetDocValuesFacetCounts.getTopDims(SortedSetDocValuesFacetCounts.java:57)
            at org.apache.lucene.facet.sortedset.TestGetTopDimsAllDims.testGetTopDimsMaxValueReturnsAllDims(TestGetTopDimsAllDims.java:53)

# main 645d4fe14a20, gradle, -Ptests.seed=DEADBEEF -Ptests.asserts=true; the same with -Ptests.asserts=false.
# On the 10.6.0 release jars (-ea and -da) the frames are AbstractSortedSetDocValueFacetCounts$1.<init>(...:153) and getTopDims(...:152).

Why it looks unintended

  • The javadoc promises getAllDims cut to the first topNDims, and the default getTopDims, which these overrides optimize, caps with Math.min(topNDims, allResults.size()).
  • The only checks reject topNDims <= 0; upstream tests already call getTopDims(10, 10) on 2 dims and expect the getAllDims(10) result.
  • The taxonomy child queue in the same class caps with Math.min(taxoReader.getSize(), topN).
The full argument248 words
  • The contract was asked for in review. Greg Miller (gsmiller) asked in the #747 review for the sentence "results should be the same as calling getAllDims and then only using the first topNDims, but may be more efficient" (discussion_r829308926, 2022-03-17); it is Facets.java:61-62.
  • The overrides optimize a capped default. The same commit (#747) added the default getTopDims with Math.min(topNDims, allResults.size()) and the uncapped SSDV override; Greg Miller's LUCENE-10488 issue (#11524) describes the other overrides as doing the same work "more optimally". For this input the pre-sizing is what makes the overrides diverge: with the cap they return the default's result in all five classes.
  • The input is in contract. validateTopN and the taxonomy check accept every positive value (Facets.java:80-84, TaxonomyFacets.java:596-598); no javadoc names an upper bound.
  • Tests. "test getTopDims(10, 10) and expect same results from getAllDims(10)" runs on 2 dims in TestSortedSetDocValuesFacets.java:128-130 and on 2 dims in TestTaxonomyFacetCounts.java:151-153; Integer.MAX_VALUE is the same call at the end of the accepted range.
  • Precedents. Michael McCandless capped the taxonomy child queue with Math.min(taxoReader.getSize(), topN) in LUCENE-5339 (#6403, 189feaacb6f), the change that moved the existing Integer.MAX_VALUE child-count test to getTopChildren(Integer.MAX_VALUE, "dim") (the cap is still at TaxonomyFacets.java:250-251). In LUCENE-4938 (#6002) Robert Muir reported an OutOfMemoryError, Uwe Schindler found that IndexSearcher did not apply the Math.min() logic everywhere, and Robert Muir asked for tests with Integer.MAX_VALUE. The hunt's intended-lens cross-model reviewer (OpenAI GPT-5.6) first pointed to that precedent and to the getTopDims(10, 10) tests.
The devil's-advocate check211 words

The strongest case for "works as designed": Facets is @lucene.experimental; getAllDims is the API for all dims; PriorityQueue rejects impossible capacities on purpose (SOLR-5661 and 4c646dab3fb, Michael McCandless, crediting rsaavedraf) and documents that it pre-allocates; the javadoc says "should" and itself qualifies the feature (dims "should be configured as requiring dim counts", Facets.java:62-64); topNDims can be read as a caller-chosen resource bound; LUCENE-4938 sits under Optimizations in CHANGES. A later cross-model fact check rated this case moderate.

Why it fails: the PriorityQueue guard is an internal limit of a @lucene.internal class whose message names a maxSize the caller never passed, not the input domain of getTopDims; the "should" is the equivalence the reviewer asked for, and the default implementation honours it for the same input; the dim-count note is about count accuracy (the repro's dims are flat and single-valued, and the queue size does not depend on the setting); read as a resource bound, topNDims still does not explain why the default returns both dims and the overrides throw; and the LUCENE-4938 thread treated a missing Math.min on a top-N queue as a defect. Verdict: not intended, a defect (low severity). A maintainer may still answer "use getAllDims"; the javadoc and the capped default are the reply.

Suggested fix

Recommended A: cap the dimension queue at the label / ordinal count (validated)

Cap the dimension queue the way the taxonomy child queue already is: Math.min(topNDims, state.getSize()) in the SortedSetDocValues getTopDims and Math.min(topNDims, taxoReader.getSize()) in TaxonomyFacets.getTopDims. With it the repro and the whole facet module (307 tests) pass. The cap is the label or ordinal count, not the dim count, so it stays loose for large fields.

// AbstractSortedSetDocValueFacetCounts.getTopDims
PriorityQueue.usingComparator(
    // there cannot be more dims than labels:
    Math.min(topNDims, state.getSize()),
    ...);

// TaxonomyFacets.getTopDims
PriorityQueue.usingComparator(
    // there cannot be more dims than ordinals:
    Math.min(topNDims, taxoReader.getSize()),
    ...);
All options and trade-offs4 options · 527 words

Option A was applied in a scratch worktree of 645d4fe14a20 and run with gradle; the hunt's checks validated the same diff. Options B and C were not built.

A: cap the dimension queue at the label / ordinal count (validated) (recommended)

One Math.min per site, mirroring the taxonomy child-queue cap (TaxonomyFacets.java:250-251): state.getSize() ("Number of unique labels") in AbstractSortedSetDocValueFacetCounts.getTopDims (:153-157) and taxoReader.getSize() in TaxonomyFacets.getTopDims (:610-614).

// AbstractSortedSetDocValueFacetCounts.getTopDims
PriorityQueue.usingComparator(
    // there cannot be more dims than labels:
    Math.min(topNDims, state.getSize()),
    ...);

// TaxonomyFacets.getTopDims
PriorityQueue.usingComparator(
    // there cannot be more dims than ordinals:
    Math.min(topNDims, taxoReader.getSize()),
    ...);

Trade-offs

  • Safe: every SSDV dim with a count has at least one label ordinal and every taxonomy dim is an ordinal, so the dims that can enter the queue never exceed the cap; results are unchanged for every topNDims that works today. The loops still test pq.size() < topNDims (AbstractSortedSetDocValueFacetCounts.java:201, TaxonomyFacets.java:653); that stays safe for the same reason, but a cleaner patch keeps the capped size in a local and uses it in both places.
  • Loose: the bound is the field's label count (SSDV) or the taxonomy's ordinal count, not the dim count. With this fix, for 2 dims in a taxonomy of 524,293 ordinals, a call allocated 2,099,320 bytes at Integer.MAX_VALUE against 2,160 at topNDims 2 (SSDV: 2,102,680 against 134,536). It removes the exception but does not make the allocation proportional to the dims; in theory a field or taxonomy with at least ArrayUtil.MAX_ARRAY_LENGTH labels or ordinals would still reach the guard.

What the checks validated

  • Gradle on 645d4fe14a20 with the fix: the repro passes with -Ptests.asserts=true and false; the whole facet module passes, 307 tests in 40 classes, 7 skipped, 0 failures (seed DEADBEEF, assertions on), including TestSortedSetDocValuesFacets, TestTaxonomyFacetCounts, TestTaxonomyFacetAssociations, TestTaxonomyFacetValueSource and TestDrillSideways. With the fix reverted the repro fails again.
  • The probe: with the fix all five classes return a and b for Integer.MAX_VALUE and allocate 1,408-1,744 bytes at 2^24.
  • Earlier: the finder's 6-test JUnit 6 of 6, an independent reproducer's 7 of 7 (-ea, -da), 7 upstream facet test classes (82 tests, together with the LFV-994 fix) and the differential harness (0 saturation and 0 allocation failures with both fixes; its remaining prefix failures belong to LFV-363 and go to 0 with that fix added).

B: cap at the number of dims (tighter; not built)

SSDV: count state.getDims() (an Iterable<String>, one pass over the dims). Taxonomy: count the root's children first (one sibling walk) or collect the dims into a growable list. Suggested by the independent root-cause-lens reviewer (OpenAI GPT-5.6).

Trade-offs

Removes the looseness of A, at the cost of one extra pass over the dims per call.

C: do not pre-size; collect the dims, then select the top topNDims (not built)

Gather the dim values into a list and pick the top topNDims from it.

Trade-offs

Removes the pre-allocation entirely; a larger change to two optimized methods.

Not recommended: reject large topNDims in validateTopN

Add an upper bound to the argument check.

Trade-offs

It would turn the working default getTopDims, and the working getTopChildren(Integer.MAX_VALUE, ...) of taxonomy facets that upstream tests use, into errors.

Downstream note

Services that pass a user-chosen number of dims straight to getTopDims on SortedSetDocValues or taxonomy facets should cap it, or call getAllDims: values from 2,147,483,631 up fail, and large values below that reserve heap in proportion to the value.

How it was found

AI tools probing numeric limits passed Integer.MAX_VALUE as topNDims to the facet implementations: SortedSetDocValues and taxonomy getTopDims threw. A model-based differential harness (any topNDims at least the dim count must give the getAllDims result) confirmed it on 40 random indexes; one minimal test reproduces it.

The method in full156 words

Method: non-formal first signal, then semi-formal checking (an executed probe, then model-based differential testing on the stock jars).

  • A planning AI tool for numeric-limit hunts read the facet code and ran a probe on main a9779ef3c193, 10.5.2, 9.12.3 and the 10.6 release candidate: SSDV getTopDims(Integer.MAX_VALUE, 10) threw and getTopDims(10^8, 10) allocated 381 MiB.
  • The hunting AI tool wrote a reference model of top-N facet results (saturation: getTopDims(n, k) for n at least the number of dims equals getTopDims(1000, k) and getAllDims(k); allocation bounded by the dims) and a differential harness over 40 seeded random indexes: on stock main 9,924 of 59,600 saturation checks and 3,060 of 14,900 allocation checks failed (these include the sibling child-queue sites, LFV-994), and 0 of each with both fixes. An SMT solver checked the queue-size arithmetic.
  • It reduced the case to a public-API JUnit over all five classes with a default-getTopDims control, and later to the one-test repro.

Prior reports, history and checks

Prior reports

No prior report found in GitHub issues, PRs and commits (incl. the JIRA archive), the mailing lists, downstream trackers, the web and all 414 open PRs; re-checked twice on 2026-10-30. Not fixed upstream: the fix-site files last changed in #16056 and #14761, both unrelated.

Searches4 searches

No report of this bug was found, and nothing upstream fixes it. Context only: #11361/#747 and #11524/#777/#779/#806/#889 (introduced the overrides; no discussion of the queue size); open PR #13287 (stefanvodita, edits TaxonomyFacets.getTopDims for a zero-value check, not the queue); open PRs #12862 and #16847 (touch the fix-site files, not the queue); the precedents #6002 (LUCENE-4938), #6403 (LUCENE-5339) and SOLR-5661; #7886 (LUCENE-6828, open, core hit-queue pre-allocation). LFV-363 and LFV-368 are other bugs on other lines of the same two methods; LFV-994 is the same pattern at the SSDV child queue.

What was searched, when, and what turned up
WhereWhenHowFound
GitHub issues, PRs, commits (apache/lucene incl. the migrated JIRA archive; Solr, OpenSearch, Elasticsearch, Lucene.NET, nrtsearch)2026-10-28 to 2026-10-29two automated passes (code terms; use case), 16 issue/PR, 3 commit and 2 downstream queries each; 39 manual searches, e.g. getTopDims(Integer.MAX_VALUE, topNDims, DimValue, TopOrdAndNumberQueue, "maxSize must be", PriorityQueue pre-allocation; the comments of #747, #777, #779, #806, #889, #915, #12966, #14761, #13287, #751, #843 readno report; context only
JIRA (LUCENE, SOLR), lists.apache.org (dev@, java-user@, issues@, commits@), the web2026-10-294 JIRA, 20 mailing-list and 15-16 web queries per passno report
All 414 open apache/lucene PRs; open module:facet items2026-10-29changed-file lists against the fix-site files#12862, #16847 and #13287 touch the files, none the queue
GitHub search, re-checks2026-10-30 (twice)getTopDims, topNDims, facet items created since 2026-10-29, "maxSize must be", PriorityQueue maxSize facet; upstream commits since 645d4fe14a20only the known items; no facet commit upstream

History

Introduced with the API: LUCENE-10325 (#747, 7c33f04d374, 2022-03-28) added the capped default and the uncapped SortedSetDocValues override together; LUCENE-10488 (#777, #779, #806) added the uncapped concurrent and taxonomy overrides. First released in 9.2.0; every release since, 10.6.0 and main fail. Not a regression.

Versions tested6 rows

LUCENE-10325 (#11361; PR #747, 7c33f04d3746, Yuting Gan, 2022-03-28; branch_9x backport 77ccf2fb359e, #773, by Greg Miller) added Facets#getTopDims with the capped default and the SSDV override with new PriorityQueue<>(topNDims). LUCENE-10488 (#11524, 2022-05-13) added the same uncapped queue to ConcurrentSortedSetDocValuesFacetCounts (ef43242d77a2, #777), IntTaxonomyFacets (57f8cb2fd6bc, #779) and FloatTaxonomyFacets (f0ec22616723, #806); backport 87655fd015ce (#889). Later changes kept the capacity: #915 (9.3.0, SSDV overrides merged into the shared base class), #12966 (9.11.0, taxonomy overrides merged into TaxonomyFacets), #14761 (main only, PriorityQueue.usingComparator).

Release-portable main() programs ran the same 2-dim data on each version with assertions off: getTopDims(1000, 10) equals getAllDims(10) everywhere, getTopDims(Integer.MAX_VALUE, 10) throws and getTopDims(2^24, 10) allocates about 64 MiB, while a default-getTopDims control passes. Releases between the executed ones are affected by git grep on every 9.x and 10.x tag (4 override sites in 9.2.0, 3 in 9.3.0-9.10.0, 2 from 9.11.0 on).

Versions and branches executed, with results
Version or commitVerdictResult
main 645d4fe14a20 affectedminimal repro fails with gradle, assertions on and off; probe: all five classes throw, about 64 MiB at 2^24
10.6.0 (4ae946e5a9b9) affectedminimal repro fails on the release jars, -ea and -da; the same commit as branch_10_6 head, where all five classes throw
main a9779ef3c193, 10.5.2 affectedall five classes throw; about 64 MiB at 2^24; the finder's JUnit 5 of 6 fail
9.10.0, 9.11.0, 9.12.3, 10.0.0 affectedthrow (10.0.0: the three core classes run); about 64 MiB at 2^24
9.2.0, 9.3.0 first release9.2.0: all five classes throw (4 override sites); 9.3.0: the three core classes throw
9.1.0 no APIno getTopDims (compile error "cannot find symbol")

Independent checks

The finder, an independent reproducer, an intended-behaviour devil's advocate, an adjudication, a credibility audit and this page's gradle runs all reproduce it. Cross-model reviews (OpenAI GPT-5.6) could run nothing: some said real, the others "not real" for procedure only; separate re-runs failed as claimed.

Checks and verdicts382 words

Every executing check ran on the stock jars and voted real. The only dissent is procedural: a cross-model refute review that could not run any code voted not real on procedure only at low confidence, while every evidence item it listed supports real.

Each independent check and its verdict
CheckVerdictWhat it found
Planning probe first signalSSDV getTopDims(Integer.MAX_VALUE, 10) throws on main, 10.5.2, 9.12.3 and the 10.6 release candidate; 381 MiB at 10^8.
Finder candidateDifferential harness (failures drop to 0 with the fixes); JUnit 5 of 6 fail on main (-ea, -da), 10.5.2 and 9.12.3; the default-getTopDims control passes; 6 of 6 and 82 upstream facet tests pass with the fix.
Cross-model reviews, intended and refute lenses (OpenAI GPT-5.6, read-only) real, medium; not real, low (procedural)Could not run code; the intended lens rated the intended argument weak and raised the LUCENE-4938 precedent; the refute lens listed only supporting evidence. Both separate re-runs: 5 of 6 fail.
Independent reproducer realOwn JUnit over all five classes: 6 of 7 fail on main (-ea, -da), 10.5.2, 9.12.3, 9.2.0; own Math.min patch 7 of 7; 1,496 vs 67,110,352 bytes; OutOfMemoryError at 2^28 with 512 MB.
Root-cause adversary (OpenAI GPT-5.6, read-only) real, mediumRoot cause agrees; the fix bound is loose (measured); suggested the tighter dim-count bound.
Intended-behaviour devil's advocate realBuilt the strongest works-as-designed case and rated it weak; re-runs fail on main and 10.5.2.
Adjudication confirmed, highRe-ran the independent JUnit with a new seed: 6 of 7 fail (-ea, -da), the control passes.
Credibility audit keepRe-ran the finder's JUnit with a new seed: 5 of 6 fail.
This page reproduced; fix validatedGradle on 645d4fe14a20: the repro fails (-ea, -da) and passes with the fix (-ea, -da); facet module 307 tests, 0 failures with the fix; 10.6.0 release jars fail (-ea, -da).
Fact checks of this page reproduced; wording correctedRe-ran the gradle repro (assertions on and off), the standalone runner on main, 10.6.0 and 9.2.0, the fix (facet module 307 tests, 0 failures) and an own probe; found three wording errors, fixed in this version. A read-only cross-model fact check (OpenAI GPT-5.6) found the commit count and wording points (an unpublished file; resolution in an unpublished file).

Diagram file

The diagram as a still image, generated with AI and checked against the code. It is under 10 MB, the limit for a GitHub attachment.

Sources and provenance

Finding record, Lucene and upstream sources, repro files and diagram notes1,514 words

Finding record

LFV-983, snapshot of 2026-11-06

Registry title
SortedSetDocValues and taxonomy Facets#getTopDims size their dimension priority queue by the caller's topNDims without a cap, so getTopDims(Integer.MAX_VALUE, n) throws IllegalArgumentException where getAllDims(n) and the default Facets#getTopDims return every dim, and a large topNDims allocates topNDims + 1 queue slots even for 2 dims
Area
facet / getTopDims dimension queue (AbstractSortedSetDocValueFacetCounts and TaxonomyFacets overrides, inherited by SortedSetDocValuesFacetCounts, ConcurrentSortedSetDocValuesFacetCounts, FastTaxonomyFacetCounts, TaxonomyFacetIntAssociations and TaxonomyFacetFloatAssociations)
Priority
Low, rank 644: GetTopDims(Integer.MAX_VALUE, n) on SSDV and taxonomy facets throws a clear IllegalArgumentException and large values only waste memory, the same loud MAX_VALUE idiom as LFV-994 on a less-used facet call, so it follows that row.
Impact class
crash
Impact note
Applications that call Facets#getTopDims(topNDims, topNChildren) on SortedSetDocValues facets (SortedSetDocValuesFacetCounts, ConcurrentSortedSetDocValuesFacetCounts) or taxonomy facets (FastTaxonomyFacetCounts, TaxonomyFacetIntAssociations, TaxonomyFacetFloatAssociations) with Integer.MAX_VALUE (or any value >= 2147483631) as 'all dims' get an IllegalArgumentException ('maxSize must be >= 0 and < 2147483631') on every such call, and with a large but legal topNDims pay one transient allocation of topNDims + 1 references per call however few dims exist (about 64 MiB at 2^24 for 2 dims; an OutOfMemoryError at 2^28 with a 512 MB heap); default FacetsConfig, codec and searcher, any index size, -ea and -da, every release from 9.2.0 to 10.6.0 and main; results for ordinary sizes are correct, getAllDims(n) is a working alternative, and nothing is written to the index.
Summary
You index two flat facet dims, call getAllDims(10) on SortedSetDocValuesFacetCounts or FastTaxonomyFacetCounts and get both dims, then call getTopDims(Integer.MAX_VALUE, 10) to ask for 'all dims' and expect the same list, because the getTopDims javadoc says results should be the same as calling getAllDims and then only using the first topNDims, and the default Facets#getTopDims caps with Math.min(topNDims, allResults.size()). Instead the optimized overrides in AbstractSortedSetDocValueFacetCounts and TaxonomyFacets build PriorityQueue.usingComparator(topNDims, ...) before they look at any dim, so the call throws IllegalArgumentException 'maxSize must be >= 0 and < 2147483631; got: 2147483647' in all five SortedSetDocValues and taxonomy implementations. Below that limit the same line pre-allocates topNDims + 1 slots: getTopDims(2^24, 10) over 2 dims allocates about 64 MiB to return 2 results.
Introduced
7c33f04d3746f855479da5177df8f19b6fdbbe84 ('LUCENE-10325: Add getTopDims functionality to Facets (#747)', issue #11361; branch_9x backport 77ccf2fb359e, #773) [read: git blame and log in the history clone, confirmed by the 9.1.0 / 9.2.0 runs]: SortedSetDocValuesFacetCounts.getTopDims built new PriorityQueue<>(topNDims), while the same commit added the capped default Facets#getTopDims. The concurrent-SSDV and taxonomy overrides came with the same uncapped queue in LUCENE-10488 (issue #11524): ef43242d77a2 (#777, ConcurrentSortedSetDocValuesFacetCounts), 57f8cb2fd6bc (#779, IntTaxonomyFacets) and f0ec22616723 (#806, FloatTaxonomyFacets), branch_9x backport 87655fd015ce (#889). Written by Yuting Gan (Yuti-G), merged by Greg Miller (gsmiller), who also authored the backports. Later refactors kept the capacity: 8db1e41fc07 (#915, SSDV overrides merged into AbstractSortedSetDocValueFacetCounts), 9ba4af7b883 (#12966, taxonomy overrides merged into TaxonomyFacets) and a7704f5242d (#14761, PriorityQueue.usingComparator). Not a regression. (2022-03-28 (SSDV site, author date of 7c33f04d374, equal to its commit date); 2022-05-13 (concurrent-SSDV and taxonomy sites, LUCENE-10488))
First affected version
9.2.0 [exec, -da]: all five classes throw for getTopDims(Integer.MAX_VALUE, 10) and allocate about 64 MiB for getTopDims(2^24, 10) over 2 dims; 9.1.0 has no Facets#getTopDims [exec: compile error 'cannot find symbol: method getTopDims(int,int)']
Affected versions
every release from 9.2.0 to 10.5.2 (all 9.2.x-9.12.x and 10.x), 10.6.0 (released 2026-10-29; run as its RC, branch_10_6 head 4ae946e5a9b9) and main a9779ef3c193; never fixed. [exec] follow-up history runs (release-portable main() over the core and facet jars, -da): 9.2.0, 9.3.0, 9.10.0, 9.11.0, 9.12.3, 10.0.0, 10.5.2, branch_10_6 and main all FAIL, with the default-getTopDims control passing on each; the finder's JUnit on main (-ea, -da), 10.5.2 and 9.12.3; the independent reproduction's JUnit on main (-ea, -da), 10.5.2 (-ea, -da), 9.12.3 and 9.2.0; the intended-behaviour check on 10.5.2. [read] the releases in between: git grep on every 9.x/10.x release tag finds the topNDims-sized dim queue at each override site (4 sites in 9.2.0, 3 in 9.3.0-9.10.0, 2 from 9.11.0 on) and no Math.min(topNDims ...) in the facet module except the default Facets#getTopDims. Upstream main 645d4fe14a (2026-10-28) has no change at the fix sites. JDK 25.0.3, aarch64; plain Java arithmetic.
Status
documented (brief, checks and a per-finding doc exist)
Verification
Confirmed by AI-run checks: an independent repro, a cross-model review that could only read the code (its low-confidence “not real” is procedural), an intended-behaviour check, a prior-report search and a skeptical audit; not yet triaged by a person.
Found by
non-formal: code reading; also reached by Z3
Upstream and prior reports
none found (2026-10-29, read-only; the prior-report record verdict new, plus the finder's search at 2026-10-28, the independent reproduction's and the intended-behaviour check's searches, the adjudication's refresh and a recheck): two scripted prior-report searches (by code terms and by use case; 16 GitHub issue/PR, 3 commit, 2 downstream, 20 mailing-list over dev@, java-user@, issues@ and commits@, 4 JIRA-archive and 15-16 web queries each; 122 and 230 distinct hits, 0 and 1 high, the high one the sandbox PR #13568), manual apache/lucene GitHub searches ('topNDims', 'getTopDims' in bodies and comments, open getTopDims items, Integer.MAX_VALUE variants, DimValue, TopOrdAndNumberQueue, PriorityQueue sizing terms), searches in Solr, OpenSearch, Elasticsearch, Lucene.NET and nrtsearch, the changed files of all 414 open apache/lucene PRs, all open module:facet items and those closed since 2026-01-01, all 93 items updated since 2026-10-26, the commits on the three fix-site files by author date, the comments and review comments of the introducing and later PRs (#747, #777, #779, #806, #889, #915, #12966, #14761 and others), JIRA REST (LUCENE, SOLR), lists.apache.org and 16 web searches. Recheck: 'getTopDims' (issues and PRs, by update) finds only the known items; no facet issue or PR was updated since 2026-10-27; none of the PRs created since 2026-10-27 or issues created since 2026-10-28 concerns facets (titles read); the last lucene/facet commit is 5017142089 (#16783, author date 2026-10-12, unrelated); tracking issue #16937 does not mention facets or getTopDims. Related, not this bug: #11361/#747 and #11524/#777/#779/#806/#889 (introduced the overrides; no sizing discussion), open PR #13287 (stefanvodita: the zero-value check in TaxonomyFacets.getTopDims, not the queue size), open PRs #12862 and #16847 (touch the fix-site files, not the queue), the precedents #6002 (LUCENE-4938), #6403 (LUCENE-5339) and SOLR-5661, and open #7886 (LUCENE-6828, core hit-queue pre-allocation).
Lucene commit tested
main 645d4fe14a20 (2026-10-28; upstream main 2f424fd428da of 2026-10-30 has no change at the fix sites): the minimal repro with gradle, assertions on and off, stock and with the fix, and the whole facet module test suite with the fix (307 tests, 0 failures), in a scratch worktree removed after the runs; the standalone runner on the 10.6.0 release jars with -ea and -da; an executed probe of the repro index over all five classes (results and allocations, stock and with the fix, -ea and -da; 10.5.2 -da). Earlier: the finder's, an independent reproducer's, a devil's advocate's, an adjudication's and an audit's tests on main a9779ef3c193 (no facet or PriorityQueue change up to 645d4fe14a20), 10.5.2, 9.12.3 and 9.2.0; release-portable main() programs on 9.1.0 to 10.5.2 and the 10.6 branch. OpenJDK 25.0.3, Linux aarch64.

Lucene and upstream sources

Finding record
  • lucene/facet/src/java/org/apache/lucene/facet/Facets.java:25 (at a9779ef3c193) (@lucene.experimental), :58-72 (getTopDims javadoc 'Results should be the same as calling getAllDims and then only using the first topNDims'; default body subList(0, Math.min(topNDims, allResults.size()))), :80-84 (validateTopN rejects only topN <= 0)
  • lucene/facet/src/java/org/apache/lucene/facet/sortedset/AbstractSortedSetDocValueFacetCounts.java:143-157 (at a9779ef3c193) (getTopDims: validateTopN, then PriorityQueue.usingComparator(topNDims, ...) at :153-154); lucene/facet/src/java/org/apache/lucene/facet/taxonomy/TaxonomyFacets.java:595-614 (getTopDims: 'topN must be > 0', then PriorityQueue.usingComparator(topNDims, ...) at :610-611) and :250-251 (child queue new TopOrdAndIntQueue(Math.min(taxoReader.getSize(), topN)))
  • lucene/core/src/java/org/apache/lucene/util/PriorityQueue.java:113-125 (at a9779ef3c193) (IllegalArgumentException for maxSize >= ArrayUtil.MAX_ARRAY_LENGTH, commented 'Throw exception to prevent confusing OOME'; maxSize + 1 slots pre-allocated below it)
  • lucene/facet/src/test/org/apache/lucene/facet/sortedset/TestSortedSetDocValuesFacets.java:127-129 (at a9779ef3c193) and lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts.java:151-153 ('test getTopDims(10, 10) and expect same results from getAllDims(10)', with fewer than 10 dims)
The finding in 30 seconds
  • Lucene main 645d4fe14a20: lucene/facet/src/java/org/apache/lucene/facet/Facets.java:25, :59-72, :80-84
  • Lucene main 645d4fe14a20: lucene/facet/src/java/org/apache/lucene/facet/sortedset/AbstractSortedSetDocValueFacetCounts.java:143-157, :162, :201-202; sortedset/SortedSetDocValuesFacetCounts.java:57; sortedset/ConcurrentSortedSetDocValuesFacetCounts.java:52
  • Lucene main 645d4fe14a20: lucene/facet/src/java/org/apache/lucene/facet/taxonomy/TaxonomyFacets.java:250-251, :595-614, :620; taxonomy/FastTaxonomyFacetCounts.java:40; taxonomy/IntTaxonomyFacets.java:28; taxonomy/FloatTaxonomyFacets.java:27; taxonomy/TaxonomyFacetIntAssociations.java:38; taxonomy/TaxonomyFacetFloatAssociations.java:51
  • Lucene main 645d4fe14a20: lucene/core/src/java/org/apache/lucene/util/PriorityQueue.java:34, :39, :61-64, :79-80, :113-134; lucene/core/src/java/org/apache/lucene/util/ArrayUtil.java:33-34
  • Lucene main 645d4fe14a20: grep 'List<FacetResult> getTopDims' over lucene/ outside tests: Facets.java:69, AbstractSortedSetDocValueFacetCounts.java:143, TaxonomyFacets.java:595
  • Lucene main 645d4fe14a20: lucene/facet/src/java/org/apache/lucene/facet/sortedset/SortedSetDocValuesFacetCounts.java:86-88, sortedset/ConcurrentSortedSetDocValuesFacetCounts.java:80-84 (hasCounts); taxonomy/TaxonomyFacetFloatAssociations.java:54, :67 (the two constructors the probe used); Facets.java:62-64 (dim-count note)
Who is affected
  • Lucene main 645d4fe14a20: lucene/facet/src/java/org/apache/lucene/facet/sortedset/AbstractSortedSetDocValueFacetCounts.java:147-149; taxonomy/TaxonomyFacets.java:600-602; Facets.java:25 (@lucene.experimental)
  • Lucene main 645d4fe14a20: grep 'List<FacetResult> getTopDims' over lucene/ outside tests (only Facets, AbstractSortedSetDocValueFacetCounts and TaxonomyFacets define it)
  • Lucene main 645d4fe14a20: lucene/facet/src/java/org/apache/lucene/facet/sortedset/ConcurrentSortedSetDocValuesFacetCounts.java:80-84 (hasCounts always true); sortedset/SortedSetDocValuesFacetCounts.java:86-88; taxonomy/FastTaxonomyFacetCounts.java:74-82
Minimal repro
  • Lucene main 645d4fe14a20: lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java:26, :28-34 (constructor deprecated; INSTANCE); a Lucene clone releases/lucene/10.6.0 (the same)
Why it looks unintended
  • Lucene main 645d4fe14a20: lucene/facet/src/java/org/apache/lucene/facet/Facets.java:59-72, :80-84; taxonomy/TaxonomyFacets.java:250-251, :596-598; lucene/core/src/java/org/apache/lucene/util/PriorityQueue.java:39, :121-125
  • Lucene main 645d4fe14a20: lucene/facet/src/test/org/apache/lucene/facet/sortedset/TestSortedSetDocValuesFacets.java:82-83, :119-120, :128-130; lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts.java:80-101 (dims Author and Publish Date), :149-153
Suggested fix
  • Lucene main 645d4fe14a20: lucene/facet/src/java/org/apache/lucene/facet/sortedset/SortedSetDocValuesReaderState.java:164-165 (getSize: number of unique labels), :184 (getDims is an Iterable); sortedset/AbstractSortedSetDocValueFacetCounts.java:201; taxonomy/TaxonomyFacets.java:250-251, :653
History
  • a Lucene clone releases/lucene/10.6.0 = 4ae946e5a9b99d1e22c23865c99e561b8dcc9d71

Other statements trace to the hunt's working files (models, logs, reviews and briefs), which are not published.

Repro files

About the diagrams

The values come from the code at that commit, the minimal repro and an executed probe of the same index.

Built 2026-11-06 from the hunt's record of this finding and its doc file. Lucene main under test in this hunt: ea57360912ed. Every listed finding was re-run on Lucene main e1faeba08bde on 2026-11-02.