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