apache/rocketmq · error · RemotingCommandException

Failed to ack message

Error message

Failed to ack message

What it means

In the pop-consumer KV ack path (appendAckNew), after successfully writing revive/ack entries the processor calls store APIs (e.g. getMaxOffsetInQueue during ack processing) whose checked ConsumeQueueException is wrapped as RemotingCommandException('Failed to ack message'). It signals the ack could not be completed against the message store even though the request reached the ack logic.

Source

Thrown at broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java:382

                        break;
                    }
                    long offset = startOffset + i;
                    if (offset < minOffset || offset > maxOffset) {
                        continue;
                    }
                    if (reviveQueueId == KeyBuilder.POP_ORDER_REVIVE_QUEUE) {
                        ackOrderlyNew(topicId, groupId, queueId, offset, popTime, invisibleTime, channel, response);
                    } else {
                        this.brokerController.getPopConsumerService().ackAsync(
                            popTime, invisibleTime, groupId, topicId, queueId, offset);
                    }
                    ackCount++;
                }

                this.brokerController.getBrokerStatsManager().incBrokerAckNums(ackCount);
                this.brokerController.getBrokerStatsManager().incGroupAckNums(groupId, topicId, ackCount);
            } catch (ConsumeQueueException e) {
                throw new RemotingCommandException("Failed to ack message", e);
            }
        }
    }

    private void handlePutMessageResult(PutMessageResult putMessageResult, AckMsg ackMsg, String topic,
        String consumeGroup, long popTime, int qId, int ackCount) {
        if (putMessageResult.getPutMessageStatus() != PutMessageStatus.PUT_OK
            && putMessageResult.getPutMessageStatus() != PutMessageStatus.FLUSH_DISK_TIMEOUT
            && putMessageResult.getPutMessageStatus() != PutMessageStatus.FLUSH_SLAVE_TIMEOUT
            && putMessageResult.getPutMessageStatus() != PutMessageStatus.SLAVE_NOT_AVAILABLE) {
            POP_LOGGER.error("put ack msg error:" + putMessageResult);
        }
        brokerController.getBrokerMetricsManager().getPopMetricsManager().incPopReviveAckPutCount(ackMsg, putMessageResult.getPutMessageStatus());
        brokerController.getPopInflightMessageCounter().decrementInFlightMessageNum(topic, consumeGroup, popTime, qId, ackCount);
    }

    protected void ackOrderly(String topic, String consumeGroup, int qId, long ackOffset, long popTime,
        long invisibleTime, Channel channel, RemotingCommand response) {

View on GitHub (pinned to 293f588571)

Solutions

  1. Inspect broker logs for the ConsumeQueueException cause and affected topic/queue
  2. Stabilize the store (fix disk issues, let recovery complete, restart if needed) before clients continue acking
  3. Skip acks for queues that no longer exist; pop revive will expire the un-acked messages
  4. Retry the ack once the broker reports the queue healthy
Defensive patterns

Strategy: retry

Try / catch

try {
    brokerController.getPopConsumerService().ackAsync(...);
} catch (RemotingCommandException e) {
    // log the ConsumeQueueException cause; queue will be redelivered via pop revive
}

Prevention

When it happens

Trigger: Ack processing with brokerConfig.popConsumerKVServiceEnable=true when a consume-queue lookup for the acked topic/queue throws: deleted queue, corrupt consumeq, or store shutdown in progress.

Common situations: Enabling the pop KV ack service and hitting store instability; topic deletion racing outstanding acks; disk errors on the store paths.

Related errors


AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14). Data as JSON: /api/errors/a71f63c2642d8d07. Report an issue: GitHub.