Introduction When a Service Bus message's lock expires before processing completes, the message becomes available for redelivery. This causes the LockLostException when the application tries to complete the message, leading to duplicate processing and potential data inconsistency.

Symptoms - Exception: "The lock supplied is invalid. Either the lock expired, or the message has already been removed" - Messages processed multiple times (duplicate handling) - Dead-letter queue growing with "MaxDeliveryCountExceeded" reason - Application logs show processing taking longer than LockDuration

Common Causes - Message processing takes longer than the queue's LockDuration (default 30 seconds) - Application hangs or stalls during message processing - AutoComplete enabled but processing fails silently - Session-based queues with long-running session locks - Network issues causing delayed CompleteAsync call

Step-by-Step Fix 1. **Check current lock duration**: ```bash az servicebus queue show --namespace-name myns --name myqueue \ --resource-group myrg --query lockDuration ```

  1. 1.Increase lock duration (maximum 5 minutes):
  2. 2.```bash
  3. 3.az servicebus queue update --namespace-name myns --name myqueue \
  4. 4.--resource-group myrg --lock-duration PT5M
  5. 5.`
  6. 6.Implement lock renewal in application code (C#):
  7. 7.```csharp
  8. 8.var processor = client.CreateProcessor(queueName, new ServiceBusProcessorOptions {
  9. 9.AutoCompleteMessages = false, MaxConcurrentCalls = 1
  10. 10.});
  11. 11.processor.ProcessMessageAsync += async args => {
  12. 12.var renewalTask = Task.Run(async () => {
  13. 13.while (!cancellationToken.IsCancellationRequested) {
  14. 14.await Task.Delay(TimeSpan.FromMinutes(2), cancellationToken);
  15. 15.await args.RenewMessageLockAsync(args.Message, cancellationToken);
  16. 16.}
  17. 17.});
  18. 18.try {
  19. 19.await ProcessMessage(args.Message);
  20. 20.await args.CompleteMessageAsync(args.Message);
  21. 21.} finally { cancellationToken.Cancel(); }
  22. 22.};
  23. 23.`

Prevention - Set LockDuration based on actual processing time (p99 + 50% buffer) - Implement automatic lock renewal for long-running handlers - Set MaxDeliveryCount to 3-5 before dead-lettering - Monitor dead-letter queue length with alerts - Use sessions for ordered processing with lock per session