Introduction
Azure Service Bus sessions enable ordered processing of related messages using session IDs. Session state stores contextual information for the session. When session state is lost, ordered processing breaks and messages may be processed incorrectly or out of order.
Symptoms
Session state not found:
{
"error": {
"code": "SessionStateNotFound",
"message": "Session state for session 'order-123' not found or expired"
}
}Session lock lost:
```bash # Application error during processing "SessionLockLostException: The session lock for session 'order-123' has been lost"
# Session accepted but state missing on next message ```
Out of order processing:
# Messages processed without session state
# Order messages 1, 2, 3 processed as 2, 1, 3
# Missing correlation between messagesCommon Causes
- 1.Session lock timeout - Processing exceeded lock duration
- 2.Session abandoned - Application abandoned session without saving state
- 3.Session expired - Session state TTL exceeded
- 4.Application crash - Session lost during processing restart
- 5.Concurrent session access - Multiple processors claiming same session
- 6.State not persisted - Application didn't save state before closing
- 7.Queue configuration issue - Session support not enabled properly
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check Session Configuration
```bash # Verify queue/session-enabled az servicebus queue show \ --name my-queue \ --namespace-name my-namespace \ --resource-group my-rg \ --query '{RequiresSession:requiresSession,LockDuration:lockDurationInSeconds}'
# For subscription az servicebus topic subscription show \ --topic-name my-topic \ --name my-subscription \ --namespace-name my-namespace \ --resource-group my-rg \ --query 'requiresSession'
# If false, enable sessions az servicebus queue update \ --name my-queue \ --namespace-name my-namespace \ --resource-group my-rg \ --requires-session true ```
Step 2: Check Session Lock Duration
```bash # Check current lock duration az servicebus queue show \ --name my-queue \ --namespace-name my-namespace \ --resource-group my-rg \ --query 'lockDurationInSeconds'
# Increase lock duration for long processing az servicebus queue update \ --name my-queue \ --namespace-name my-namespace \ --resource-group my-rg \ --lock-duration PT5M # 5 minutes
# Or implement lock renewal in application # Renew session lock periodically during processing ```
Step 3: View Active Sessions
```bash # List sessions with messages az servicebus queue show \ --name my-queue \ --namespace-name my-namespace \ --resource-group my-rg \ --query 'countDetails.{Active:activeMessageCount,Scheduled:scheduledMessageCount}'
# Use Service Bus Explorer to view session states # Or PowerShell: $namespace = "my-namespace" $queueName = "my-queue"
Get-AzServiceBusSession -NamespaceName $namespace -QueueName $queueName ```
Step 4: Get Session State
```bash # Retrieve session state using PowerShell $sessionReceiver = Accept-AzServiceBusSession -NamespaceName my-namespace -QueueName my-queue -SessionId "order-123"
$sessionState = Get-AzServiceBusSessionState -Receiver $sessionReceiver
Write-Host "Session State: $sessionState"
# Session state can be: # - Null (no state set) # - Byte array (custom application state) # - JSON (if stored as serialized object) ```
Step 5: Set Session State Before Processing
```bash # Always set session state when accepting session # Application pattern:
$sessionReceiver = AcceptSession($queuePath, sessionId);
# Get or initialize state $state = $sessionReceiver.GetSessionState(); if ($state == null) { $state = InitializeState(sessionId); }
# Process message with state context $message = $sessionReceiver.Receive(); ProcessMessageWithState($message, $state);
# Update state after processing $newState = UpdateState($state, $message); $sessionReceiver.SetSessionState($newState);
# Complete message $sessionReceiver.Complete($message);
# Close session when done $sessionReceiver.Close(); ```
Step 6: Implement Session Lock Renewal
```bash # For long-running session processing # Renew lock periodically
# Application pattern: $sessionReceiver = AcceptSession($queuePath, sessionId); $lockRenewalTimer = StartTimer(interval: 30 seconds, action: { $sessionReceiver.RenewSessionLock(); });
try { while ($sessionReceiver.HasMessages) { $message = $sessionReceiver.Receive(); ProcessMessage($message); $sessionReceiver.Complete($message); } } finally { $lockRenewalTimer.Stop(); $sessionReceiver.Close(); } ```
Step 7: Handle Session Abandonment
```bash # When abandoning session, preserve state # Wrong approach: $sessionReceiver.Abandon(); // State may be lost
# Correct approach: $currentState = $sessionReceiver.GetSessionState(); $sessionReceiver.SetSessionState($currentState); // Preserve state $sessionReceiver.Abandon();
# Or use defer for later processing: $sequenceNumber = $sessionReceiver.Defer($message); StoreDeferredSequence(sessionId, sequenceNumber); $sessionReceiver.Close(); ```
Step 8: Configure Session State Storage
```bash # Session state is stored in Service Bus # For backup, mirror to external storage
# Create storage account for session backup az storage account create \ --name sessionbackup \ --resource-group my-rg \ --location eastus
# Application pattern for state backup: $sessionState = GetSessionState(); SaveToBlobStorage($"sessions/{sessionId}/state.json", $sessionState);
# Recovery from backup: $backupState = LoadFromBlobStorage($"sessions/{sessionId}/state.json"); $sessionReceiver.SetSessionState($backupState); ```
Step 9: Prevent Concurrent Session Access
```bash # Ensure single processor per session # Use session affinity in application
# Service Bus provides single-session-lock guarantee # But applications may compete to accept session
# Pattern: # 1. Use single processor per session ID pattern # 2. Implement session ownership check # 3. Use distributed lock for session acceptance
# Scale horizontally by session ID hash: $processorId = Hash(sessionId) % NumberOfProcessors; if (processorId == MyProcessorId) { AcceptSession(sessionId); } ```
Step 10: Monitor Session Health
```bash # Monitor session metrics az monitor metrics list \ --resource /subscriptions/SUB/resourceGroups/my-rg/providers/Microsoft.ServiceBus/namespaces/my-namespace \ --metric "ActiveSessions" \ --query 'value[].timeseries[].data[].average'
# Create alert for session issues az monitor metrics alert create \ --name sb-session-issues \ --resource-group my-rg \ --scopes /subscriptions/SUB/resourceGroups/my-rg/providers/Microsoft.ServiceBus/namespaces/my-namespace \ --condition "avg SessionErrors > 10" \ --window-size 5m
Session Processing Workflow
| Phase | Action | State Handling |
|---|---|---|
| Accept | AcceptSession(sessionId) | GetSessionState() |
| Process | Receive/Complete | Update state |
| Long Process | Renew lock periodically | Keep state |
| Defer | Defer message | Preserve state |
| Close | Close session | SetSessionState() final |
Verification
```bash # After fixing session handling # Test session state persistence
# Send session messages az servicebus message send \ --queue-name my-queue \ --namespace-name my-namespace \ --body '{"orderId":"123","step":1}' \ --session-id "order-123"
Prevention
To prevent Azure Service Bus session state lost issues from recurring, implement these proactive measures:
1. Monitor Session Operations
groups:
- name: azure-servicebus-sessions
rules:
- alert: AzureServiceBusSessionStateLost
expr: |
rate(azure_servicebus_session_state_lost_total[5m]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: "Azure Service Bus session state loss detected"2. Implement State Checkpointing
```csharp // Implement regular state checkpointing public class SessionProcessor { private readonly ServiceBusSender _sender; private readonly BlobServiceClient _blobClient;
public async Task ProcessSession(ServiceBusSessionReceiver receiver, string sessionId) { var state = await receiver.GetSessionStateAsync() ?? new BinaryData("{}");
// Process message var message = await receiver.ReceiveMessageAsync();
// Update state var updatedState = UpdateState(state, message);
// Checkpoint state to both session and blob await receiver.SetSessionStateAsync(updatedState); await CheckpointToBlob(sessionId, updatedState);
// Complete message await receiver.CompleteMessageAsync(message); }
private async Task CheckpointToBlob(string sessionId, BinaryData state) { var container = _blobClient.GetBlobContainerClient("session-state-backup"); var blob = container.GetBlobClient($"sessions/{sessionId}"); await blob.UploadAsync(state, overwrite: true); } } ```
3. Configure Session Timeout Appropriately
```bash # Set appropriate lock duration for sessions az servicebus queue update \ --name my-queue \ --namespace-name my-namespace \ --resource-group my-rg \ --lock-duration PT30S # 30 seconds
# Set max delivery count az servicebus queue update \ --name my-queue \ --namespace-name my-namespace \ --resource-group my-rg \ --max-delivery-count 5 ```
Best Practices Checklist
- [ ] Monitor session operations
- [ ] Implement state checkpointing
- [ ] Configure appropriate timeouts
- [ ] Keep sessions locked during processing
- [ ] Renew locks for long operations
- [ ] Backup critical session state
Related Issues
- [Fix Azure Service Bus Dead Letter Queue Full](/articles/fix-azure-service-bus-dead-letter-queue-full)
- [Fix Azure Service Bus Message Deferral](/articles/fix-azure-service-bus-message-deferral)
- [Fix Azure Service Bus Throttling](/articles/fix-azure-cosmos-db-throttling)
Related Articles
- [Technical troubleshooting: Fix Azure Aks Pod Crashloopbackoff Issue in Azure](azure-aks-pod-crashloopbackoff)
- [Technical troubleshooting: Fix Azure Api Management Policy Expression Runtime](azure-api-management-policy-expression-runtime-error)
- [Technical troubleshooting: Fix Azure App Configuration Feature Flag Not Refre](azure-app-configuration-feature-flag-not-refreshing)
- [Technical troubleshooting: Fix Azure App Service 503 Always On Disabled Issue](azure-app-service-503-always-on-disabled)
- [Technical troubleshooting: Fix Azure Application Gateway Err SSL Unrecognized](azure-application-gateway-err-ssl-unrecognized-name-alert)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Azure Service Bus Session State Lost", "description": "Troubleshoot Service Bus session state loss. Check session handling, storage configuration, and lock timeout settings.", "url": "https://www.fixwikihub.com/fix-azure-service-bus-session-state-lost", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-03T13:16:54.838Z", "dateModified": "2026-04-03T13:16:54.838Z" } </script>