Skip to content

[Bug]: [Nightly] HNSW_SQ search returns fewer results than limit with minimum boundary params (M=2, efConstruction=1) #48919

@NicoYuan1986

Description

@NicoYuan1986

Environment

  • Milvus Version: 2.6 branch, commit 3227601
  • Deployment Mode: distributed
  • MQ: pulsar / kafka (reproduced on pulsar and woodpecker, kafka passes)
  • SDK: pymilvus (nightly CI)
  • OS: Linux (CI environment)

Reproduction

Steps

  1. Create a collection with FLOAT_VECTOR field (dim=128)
  2. Insert data in 2 batches (2 * default_nb rows)
  3. Flush
  4. Build HNSW_SQ index with minimum boundary params: M=2, efConstruction=1, sq_type=SQ6
  5. Wait for index ready
  6. Load collection
  7. Search with limit=10

Trigger Conditions

  • Frequency: consistent (reproduced on both pulsar-mmap and woodpecker deployments)
  • First observed after: Nightly build 161 on 2.6 branch (2026-04-09). Not seen in build 160.
  • Does NOT happen when: using kafka deployment (kafka passed with same test), or using non-extreme HNSW_SQ params

Expected Behavior

Search should return exactly limit=10 results.

Actual Behavior

Search returns fewer than 10 results. Additionally, some distances are negative under COSINE metric, which is abnormal.

Pulsar search result snippet:

data: [[{'id': 2972, 'distance': 0.14255018532276154, 'entity': {}}, {'id': 3526, 'distance': 0.13366436958312988, 'entity': {}}, ..., {'id': 555, 'distance': 0.00815456174314022, 'entity': {}}, {'id': 502, 'distance': -0.027767080813646317, 'entity': {}}]]

Error Logs

Test case: testcases/indexes/test_hnsw_sq.py::TestHnswSQBuildParams::test_hnsw_sq_build_params[params48]
Params: {'description': 'Minimum boundary combination', 'expected': 'success', 'params': {'M': 2, 'efConstruction': 1, 'sq_type': 'SQ6'}}

testcases/indexes/test_hnsw_sq.py:68:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
utils/wrapper.py:33: in inner_wrapper
    res, result = func(*args, **kwargs)
base/client_v2_base.py:175: in search
    **kwargs).run()
check/func_check.py:70: in run
    result = self.check_search_results(self.response, self.func_name, self.check_items)
check/func_check.py:461: in check_search_results
    assert len(hits) == check_items["limit"]
AssertionError

Non-default Configuration

Default nightly CI configuration.

Analysis Hints

Metadata

Metadata

Assignees

Labels

kind/bugIssues or changes related a bugneeds-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions