Skip to content

When recovery is enabled more deliveries can be acked after recovery than the user expects #395

Closed
@caspermout

Description

@caspermout

I found the following code in the class RecoveryAwareChannelN:

@Override
public void basicAck(long deliveryTag, boolean multiple) throws IOException {
    long realTag = deliveryTag - activeDeliveryTagOffset;
    // 0 tag means ack all when multiple is set
    if (realTag > 0 || (multiple && realTag == 0)) {
        transmit(new Basic.Ack(realTag, multiple));
        metricsCollector.basicAck(this, deliveryTag, multiple);
    }
}

When activeDeliveryTagOffset and deliveryTag are the same (this can happen directly after a channel is reconnected/recovered) this method will ack all outstanding messages instead of acking nothing.

The output of the attached sample application contains PRECONDITION_FAILED - unknown delivery tag 1 because it is trying to ack all messages. But it was already acked by acking the first message after connection recovery.

example-output.txt
TestRabbitRecover.txt

  • RabbitMQ version
    3.6.15

  • Erlang version
    Erlang 19.3.6.7

  • Client library version (for all libraries used)
    com.rabbitmq/amqp-client/4.5.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions