IndexSearcher throws IllegalArgumentException for any reader that contains a leaf with maxDoc() == 0 (for example a ParallelLeafReader with no sub-readers): the whole-segment LeafReaderContextPartition of that leaf fails a bounds check added for partition ranges (regression in 10.0.0)

Finding LFV-202Area: search / IndexSearcher slicing (LeafSlice, LeafReaderContextPartition)Priority: lowImpact: crashNovelty: new

Finding page for LFV-202

AI-assisted finding, confirmed by automated checks, not yet triaged by a human Lucene committer. This site files nothing upstream.

What it shows

You build an IndexSearcher over a reader that contains an empty leaf, for example new ParallelLeafReader() with no sub-readers, possibly next to a real index inside a MultiReader, and you expect searches to work and simply find no hits in the empty part, as they do on 9.12.3. Instead the searcher throws IllegalArgumentException 'minDocId is greater than than maxDoc: [0] > [0]', because slicing wraps every leaf in a whole-segment partition that starts at doc 0 and the partition constructor rejects a start that is not below the leaf's maxDoc(). In the repro, a MultiReader of a 5-doc index plus an empty ParallelLeafReader cannot be searched at all instead of returning 5 hits.

The test shows that new IndexSearcher(new ParallelLeafReader(true)) (a reader whose only leaf has maxDoc() == 0) cannot count a MatchAllDocsQuery.

Expected vs actual

Expected: count 0. Actual (-ea and -da): IllegalArgumentException minDocId is greater than than maxDoc: [0] > [0] from the whole-segment LeafReaderContextPartition.

Files

Run it

# Lucene checkout at the tested commit, built with: ./gradlew --no-daemon assemble   (JDK 25)
LUCENE=/path/to/lucene; V=12.0.0-SNAPSHOT
CP=$LUCENE/lucene/core/build/libs/lucene-core-$V.jar
CP=$CP:$LUCENE/lucene/codecs/build/libs/lucene-codecs-$V.jar
CP=$CP:$LUCENE/lucene/test-framework/build/libs/lucene-test-framework-$V.jar
CP=$CP:randomizedtesting-runner-2.9.2.jar:junit-4.13.2.jar:hamcrest-3.0.jar   # test-framework dependencies (Maven Central)
CP=$CP:junit-platform-console-standalone-6.1.3.jar   # JUnit Platform console launcher (Maven Central)

javac -d classes -cp "$CP" $(find src -name '*.java')

# run 1: assertions on, seed DEADBEEF
java -ea -esa --add-modules jdk.incubator.vector --enable-native-access=ALL-UNNAMED -Dtests.seed=DEADBEEF \
     -cp "classes:$CP" org.junit.platform.console.ConsoleLauncher \
     execute --select-class org.apache.lucene.search.TestSearchZeroDocLeaf

Gradle alternative: copy the test into the matching module's src/test/ tree of the checkout and run ./gradlew -p lucene/<module> test --tests <class> -Ptests.seed=<seed> (add -Ptests.asserts=false for a run without assertions).

Formal models and scripts this finding's part of the hunt used: concurrent-collector-managers

Feedback

Open an issue in lucene-ai-bug-hunt. Please do not open issues or pull requests in apache/lucene about this finding unless a Lucene committer agrees it should be filed.

Snapshot of 2026-11-04. AI-assisted; not yet triaged by a human Lucene committer. Feedback: open an issue in lucene-ai-bug-hunt.