You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by "iloveeyjafjalla (via GitHub)" <gi...@apache.org> on 2026/10/12 10:59:46 UTC
[I] [Bug] A malformed receipt handle is reported as INTERNAL_SERVER_ERROR, so official clients retry the ack forever [rocketmq]
iloveeyjafjalla opened a new issue, #11375:
URL: https://github.com/apache/rocketmq/issues/11375
### Before Creating the Bug Report
- [x] I found a bug, not just asking a question, which should be created in [GitHub Discussions](https://github.com/apache/rocketmq/discussions).
- [x] I have searched the [GitHub Issues](https://github.com/apache/rocketmq/issues) and [GitHub Discussions](https://github.com/apache/rocketmq/discussions) of this repository and believe that this is not a duplicate.
- [x] I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.
### Runtime platform environment
OS: any (proxy module, gRPC v2 consumer path)
### 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)
### Description
A receipt handle that cannot be parsed is reported as `INTERNAL_SERVER_ERROR`, not as `INVALID_RECEIPT_HANDLE`.
`ReceiptHandle.decode` throws `IllegalArgumentException` for a handle that does not parse (and `NumberFormatException`, also
an `IllegalArgumentException`, for non-numeric fields). In the gRPC v2 consumer path that exception reaches
`ResponseBuilder#buildStatus(Throwable)`, which only maps `ProxyException` / `GrpcProxyException`, topic-not-found,
`MQBrokerException`, `MQClientException`, `RemotingTimeoutException` and the auth exceptions:
```java
log.error("internal server error", t);
return buildStatus(Code.INTERNAL_SERVER_ERROR, ExceptionUtils.getErrorDetailMessage(t));
```
For an **expired** handle the code already reports the right thing — `AbstractProcessor#validateReceiptHandle` throws
`ProxyException(ProxyExceptionCode.INVALID_RECEIPT_HANDLE)` and the mapping table turns that into
`Code.INVALID_RECEIPT_HANDLE` — but a **malformed** handle takes the parse-error path instead. Concretely:
- `AckMessageActivity#processAckMessage` catches the parse failure and completes the entry with
`INTERNAL_SERVER_ERROR`;
- `AckMessageActivity#ackMessageInBatch` decodes every entry before calling the processor, so one unparseable handle fails
the whole batch request;
- `ChangeInvisibleDurationActivity` and `ForwardMessageToDeadLetterQueue` decode the same way.
This matters to the official clients: `rocketmq-clients` `ProcessQueueImpl#ackMessage` gives up on a message only for
`INVALID_RECEIPT_HANDLE` ("forgive to retry") and otherwise calls `ackMessageLater(...)`, retrying the ack every second
indefinitely. So a malformed handle produces an endless ack retry loop plus `internal server error` logs and server-error
alerts instead of a single, actionable client error — and in the batch case it also fails the valid entries of the same
request.
`service.proto` documents the expectation for `AckMessage`: "If the given receipt_handle is illegal or out of date, returns
`INVALID_ARGUMENT`", and `definition.proto` defines the dedicated `INVALID_RECEIPT_HANDLE = 40013`.
### Steps to Reproduce
1. Run a proxy and send `AckMessage` with `receipt_handle = "not-a-receipt-handle"` (one entry, or mixed with a valid entry
in a batch).
2. The entry/request status is `INTERNAL_SERVER_ERROR` instead of `INVALID_RECEIPT_HANDLE`; with `enableBatchAck=true` the
whole request fails and the valid entries are not acknowledged either.
### Expected behavior
An unparseable receipt handle is reported as `INVALID_RECEIPT_HANDLE`, exactly like an expired one, so clients drop the
message instead of retrying forever.
### Actual behavior
`INTERNAL_SERVER_ERROR` (and, in the batch path, a request-scoped failure that hides the graded reason).
### Additional context
Fix: decode receipt handles through a helper that turns the parse failure into
`ProxyException(ProxyExceptionCode.INVALID_RECEIPT_HANDLE, …)`, and use it at the ack (single + batch),
change-invisible-time and forward-to-DLQ call sites.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@rocketmq.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] [Bug] A malformed receipt handle is reported as INTERNAL_SERVER_ERROR, so official clients retry the ack forever [rocketmq]
Posted by "RockteMQ-AI (via GitHub)" <gi...@apache.org>.
RockteMQ-AI commented on issue #11375:
URL: https://github.com/apache/rocketmq/issues/11375#issuecomment-6123019728
**Issue Evaluation**
Category: `type/bug` | Status: **Confirmed**
The reported issue has been verified based on the detailed analysis provided.
**Root Cause:** `ReceiptHandle.decode` throws `IllegalArgumentException` for malformed handles, which is not caught in the gRPC v2 consumer path and falls through to the generic `INTERNAL_SERVER_ERROR` handler in `ResponseBuilder#buildStatus(Throwable)`. This bypasses the proper `INVALID_RECEIPT_HANDLE` mapping that exists for expired handles.
**Impact:**
- Official clients (`rocketmq-clients` `ProcessQueueImpl#ackMessage`) retry ack indefinitely for `INTERNAL_SERVER_ERROR`, creating endless retry loops
- Batch operations fail entirely when one entry has a malformed handle
- Server logs show misleading `internal server error` instead of actionable client error
**Severity:** High — affects message consumption reliability and causes alert noise
**Affected Components:**
- `AckMessageActivity#processAckMessage`
- `AckMessageActivity#ackMessageInBatch`
- `ChangeInvisibleDurationActivity`
- `ForwardMessageToDeadLetterQueue`
- gRPC v2 consumer path in Proxy
**Suggested Fix:** Catch `IllegalArgumentException` from `ReceiptHandle.decode` and map it to `ProxyException(ProxyExceptionCode.INVALID_RECEIPT_HANDLE)` or return `Code.INVALID_ARGUMENT` as documented in `service.proto`.
An automated fix proposal will be generated. Reply `/approve` to proceed with PR generation.
---
*Automated evaluation by RockteMQ-AI*
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org