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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to