[Bug] QueryMessage ignores the request's pagination fields and echoes a scroll_id it never issues
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 1/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 35/100
Research direction
Read the QueryMessage implementation and the ListMessageRequest and ListMessageResponse proto fields cited in the issue, then check §8 in docs/proxy-admin.md and docs/proxy-admin-zh.md. Reproduce with page_size: 1 and a second-page request. Done means the supported page-size cap is honored, unsupported page numbers and scroll IDs return BAD_REQUEST without echoing a cursor, and both docs describe the boundary.
Written by the indexing model from the issue text.
Description
Before Creating the Bug Report
- I found a bug, not just asking a question, which should be created in GitHub Discussions.
- I have searched the GitHub Issues and GitHub Discussions of this repository and believe that this is not a duplicate.
- I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.
Runtime platform environment
OS: any (proxy module, admin gRPC surface)
RocketMQ version
branch: develop
Git commit id: 9ea2ccdc2b41445aee5e177e14e501d606f5a1ed (2026-10-08)
JDK Version
Compiler: Temurin 1.8.0_504 (target 1.8, same as CI)
Describe the Bug
QueryMessage accepts the request's pagination fields and then ignores them, while answering OK.
The proto declares page-style pagination and a cursor:
// ListMessageRequest
// Page-style pagination parameters.
optional int32 page_num = 8;
optional int32 page_size = 9;
...
// ListMessageResponse
// Cursor to be passed back to fetch the next page.
optional string scroll_id = 3;
The implementation reads none of them: only max_message_nums is honored (defaulting to 32), and the response echoes the
request's scroll_id back:
int maxNums = request.getMaxMessageNums() > 0 ? request.getMaxMessageNums() : DEFAULT_MAX_MESSAGE_NUMS;
...
ListMessageResponse.Builder builder = ListMessageResponse.newBuilder().setStatus(ok());
if (request.hasScrollId()) {
builder.setScrollId(request.getScrollId());
}
Consequences:
- a caller that sets only
page_size = 10receives up to 32 messages (the default cap) instead of its page size; - a caller that asks for
page_num = 2, or that passes thescroll_idfrom the previous response back, receives the same
first page again withOK— there is no ordering or cursor behind it, so a paging client loops on the same data; - the echoed
scroll_idclaims a continuation exists that the proxy never issues.
Steps to Reproduce
- Run a proxy with
grpcAdminServerEnable=trueon a topic with more than one page of messages for a key. - Call
QueryMessage{message_key, page_size:1}— more than one message comes back. - Call it again with
page_num:2(or with thescroll_idof the first response) — the same first page comes back withOK.
Expected behavior
The fields that can be honored are honored (a page_size acts as the result cap), and the ones the open-source broker cannot
serve — page_num beyond the first page and scroll_id, which both need a cursor the broker does not provide — are refused
with an explicit status instead of silently returning an unscoped page. scroll_id is not echoed back as if a cursor existed.
This is the rule the same RPC already applies to its unsupported search_key variants (subscription / lite_topic /
SEARCHKEY_NOT_SET → BAD_REQUEST) and the documented surface rule in docs/proxy-admin.md §8.
Actual behavior
OK with an unscoped first page; page_size ignored; a scroll_id that cannot fetch anything echoed back.
Additional context
Fix: cap the result by page_size when it is set, refuse page_num > 1 and any scroll_id with BAD_REQUEST, and document
the boundary in docs/proxy-admin.md / docs/proxy-admin-zh.md §8.
- Dominant language
- Java
- Stars
- 22.7k
- Forks
- 12k
- Avg merge
- 3d 18h
- Merged PRs (30d)
- 17
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from apache/rocketmq
-
[Bug] RemotingHelper.connect swaps the socket send and receive buffer configurationPossibly taken @amalsaidov claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
CompressionType.of fails under the Turkish localePossibly taken @sharanggupta claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Maintainers usually reply within 1 day
-
[rocketmq-client-python] TransactionMQProducer allocates an unused producer during initializationOpen
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
[Bug] notifyMasterOnline aborts the long-polling wake-up with a NullPointerException when an arrival drains a bucket firstPossibly taken @iloveeyjafjalla claimed this 29 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
apache/rocketmq#11441 · 1 comment ·
Maintainers usually reply within 1 day
-
[Enhancement] FilterFactory duplicate-registration and unregister semantics lack testsPossibly taken @chennaji9 claimed this 34 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
apache/rocketmq#11340 · 2 comments ·
Maintainers usually reply within 1 day
Similar issues
-
bug emitter:client:csharp
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
microsoft/typespec#12572 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
GCC 15.2: -Wcast-qual warning - cast discards const qualifier from pointer target type (H5trace.c)Open
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
Maintainers usually reply within 1 day
-
needs-area-label
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 2 days
-
area/ai area/backend component/zeebe kind/task
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
spAnser/reacharound#38 ·