How to reprocess dead-letter messages in Service Bus Queues?
    • Dark
      Light
    • PDF

    How to reprocess dead-letter messages in Service Bus Queues?

    • Dark
      Light
    • PDF

    Article Summary

    Dead-letter messages are messages that are not delivered to the intended receiver and instead end up in a dead-letter queue. These messages can be reprocessed using two methods. The first method involves writing a custom code to reprocess the accumulated dead-letter messages in the Queue, while the following method utilizes the user interface of Service Bus Explorer present in the Azure portal.
    But before we dive into that, let’s first understand the reasons behind the dead-letter messages in a queue.

    • Exceeding Maximum Delivery Count: Message delivery exceeds the defined max delivery count. But this can be prevented by configuring the max delivery count to a more significant number.
    • TTL Expired: When message time to live property has expired.
    • Exceeding Header Size: A message’s header size exceeds the default size (64KB), including the system and custom properties.
    • Session ID Null: When a message is sent to the session id enabled queue without Session ID.
    • Exceeding Maximum Transfer Hop Count: Message forwarding between Queues has been exceeded.

    This article will further explore reprocessing the dead-letter messages using a code approach as well as the Service Bus Explorer.

    Here is the sample code snippet that can be used for reprocessing the dead-letter messages in Azure:

    Following .NET SDK is used in the code snippet: 
    Microsoft.Azure.ServiceBus 
    
    using System; 
     using System.Threading.Tasks; 
     using Microsoft.Azure.ServiceBus; 
     using Microsoft.Azure.ServiceBus.Management; 
    class Program 
     { 
         const string connectionString = "Your_Connection_String"; 
         const string queueName = "Your_Queue_Name"; 
         const string deadLetterQueueName = queueName + "/$DeadLetterQueue"; 
        static async Task Main(string[] args) 
         { 
             await ReceiveAndResubmitDeadLetterMessagesAsync(); 
       } 
       static async Task ReceiveAndResubmitDeadLetterMessagesAsync() 
         { 
             var client = new QueueClient(connectionString, queueName); 
             var managementClient = new ManagementClient(connectionString); 
            // Make sure the dead-letter queue exists 
             if (! await managementClient.QueueExistsAsync(deadLetterQueueName)) 
             { 
                 await managementClient.CreateQueueAsync(new QueueDescription(deadLetterQueueName) 
                 { 
                     AutoDeleteOnIdle = TimeSpan.FromDays(7) 
                 }); 
             } 
            // Register the message handler to receive and process dead-letter messages 
             client.RegisterMessageHandler(ProcessDeadLetterMessageAsync, new MessageHandlerOptions(ExceptionReceivedHandler) 
             { 
                 MaxConcurrentCalls = 1 
             }); 
            Console.WriteLine("Press any key to exit."); 
             Console.ReadKey(); 
            // Close the client and clean up resources 
             await client.CloseAsync(); 
         } 
      static async Task ProcessDeadLetterMessageAsync(Message message, CancellationToken cancellationToken) 
         { 
             // You can process the dead-letter message here 
             Console.WriteLine($"Received dead-letter message: {Encoding.UTF8.GetString(message.Body)}"); 
            // Resubmit the dead-letter message to the original queue 
             var client = new QueueClient(connectionString, queueName); 
             await client.SendAsync(new Message(message.Body));
            // Complete the dead-letter message to remove it from the dead-letter queue 
             await client.CompleteAsync(message.SystemProperties.LockToken); 
         } 
        static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs) 
         { 
             Console.WriteLine($"Message handler encountered an exception: {exceptionReceivedEventArgs.Exception}"); 
             return Task.CompletedTask; 
         } 
     } 
    

    Reprocess the dead-letter queue messages in the Service Bus Explorer

    Service Bus Explorer is a management tool present in Azure Portal to manage your Service Bus messages efficiently, both active and dead-letter messages, seamlessly.

    In the Service Bus Explorer, you will find options to retrieve the active messages or dead-letter messages in peek mode.

    First, retrieve the dead-letter messages in the peek mode. You also have an option to peek at messages with their sequence number. Simply provide the sequence number and number of messages you want to retrieve.

    Once you have retrieved them, the dead-letter messages will be listed with their sequence number, message ID, dead-letter reasons, and error description. Now, you can select the messages in bulk or individually and then click “Re-send selected messages” to reprocess them to the same Queue.

    If you need to edit the message body, select the messages, edit the text individually, and then proceed with reprocessing.

    Furthermore, you could also download these messages individually and view their content as an XML document.

    That’s how you reprocess the failed Service Bus messages in Service Bus Explorer. However, there are only basic features in Service Bus Explorer regarding managing and reprocessing the dead-letter messages. Dead-letter messages can only be inspected and handled manually. But, with automation, you could automatically resubmit messages based on dead-lettering reasons, reducing the manual effort and saving time.

    How do you automate the dead-letter processing?

    As we saw earlier, Service Bus Explorer has no built-in automation features for reprocessing dead-letter messages. It is suggested to explore tools available on the market, and one such tool is Azure Service Bus management tool by Serverless360.

    As part of monitoring and managing Service Bus, it offers automation features for reprocessing. Within the automated task module, you could configure to resubmit, resubmit & delete, or delete the failed messages based on the dead-letter reasons to any queue, topic subscriptions, or API Endpoint. Additionally, you could also back up these messages before resubmitting.

    Now, you can avoid accumulating dead-letter messages in the Queue and ensure the business process continues to flow without interruptions.


    Was this article helpful?