Skip to content

Retry Issues

This page describes common issues related to subscriber retry policies.


Messages Are Not Retried

A message enters the retry flow only when:

args.Acknowledged = false;
args.Requeue = true;

If either condition is not met, the retry topology is not used.

Example:

subscriber.Received.Add(
    async (sender, args) =>
    {
        try
        {
            ProcessMessage(args.Message.Data);

            args.Acknowledged = true;
        }
        catch
        {
            args.Acknowledged = false;
            args.Requeue = true;

            throw;
        }

        await Task.CompletedTask;
    });

Requeue Is False

If:

args.Acknowledged = false;
args.Requeue = false;

the message does not enter the retry flow.

Verify the handler explicitly sets:

args.Requeue = true;

when retry behavior is expected.


Retry Topology Not Created

Verify the descriptor enables retry:

RetryPolicy = new RetryPolicyDescriptor
{
    Enabled = true
};

When enabled, the provider creates:

<queue>_dlx
<queue>_retry exchange
<queue>_retry queue

Verify Retry Queue Arguments

The retry queue should contain arguments similar to:

x-message-ttl
x-dead-letter-exchange
x-queue-type

Verify them in RabbitMQ Management UI.


Messages Never Return To The Main Queue

Verify:

Retry Queue
    ↓ TTL expires
Retry Exchange
    ↓
Main Queue

If the retry exchange or binding is missing, messages remain in the retry queue.


Messages Return Immediately

Verify:

Delayed = TimeSpan.FromSeconds(...)

A very small delay may make retries appear immediate.


Retry Queue Contains Messages Forever

Possible causes:

  • invalid TTL;
  • missing dead-letter exchange;
  • missing retry exchange;
  • missing retry binding.

Verify the retry queue configuration in RabbitMQ.


Max Retry Reached

When the retry limit is reached, the message is no longer retried.

Verify any handlers attached to:

subscriber.OnMaxRetryFailed

to observe exhausted retry attempts.


Diagnostic Checklist

Verify:

  • RetryPolicy.Enabled;
  • Acknowledged = false;
  • Requeue = true;
  • retry topology creation;
  • retry queue arguments;
  • retry exchange bindings;
  • maximum retry configuration.