W3C trace context not propagated for session-enabled Service Bus triggers (OpenTelemetry)
Description
When using OpenTelemetry ("telemetryMode": "OpenTelemetry" in host.json) with session-enabled Service Bus triggers (IsSessionsEnabled = true), the W3C trace context (traceparent/tracestate) embedded in the Service Bus message is not used as the parent trace. Instead, the Functions host creates a new root activity, breaking distributed tracing across process boundaries.
Non-session Service Bus triggers propagate trace context correctly. The issue is specific to session-enabled triggers.
Root Cause
The Functions host subscribes to a hardcoded list of ActivitySource names in OpenTelemetryConfigurationExtensions.ConfigureTracing():
ReadOnlySpan<string> sources =
[
OpenTelemetryConstants.ActivitySourceNames.ServiceBusProcessor, // "Azure.Messaging.ServiceBus.ServiceBusProcessor"
OpenTelemetryConstants.ActivitySourceNames.EventHubsProcessor,
// ...
];
The list includes "Azure.Messaging.ServiceBus.ServiceBusProcessor" but is missing "Azure.Messaging.ServiceBus.ServiceBusSessionProcessor".
The Azure.Messaging.ServiceBus SDK's DiagnosticScopeFactory.GetActivitySource() (source) constructs ActivitySource names dynamically from the operation name:
string clientName = ns + "." + ((indexOfDot < 0) ? name : name.Substring(0, indexOfDot));
return ActivitySources.GetOrAdd(clientName, static n => new ActivitySource(n));
Combined with DiagnosticProperty.cs (source):
| Trigger type |
Activity name |
Resulting ActivitySource name |
Host subscribed? |
| Non-session |
ServiceBusProcessor.ProcessMessage |
Azure.Messaging.ServiceBus.ServiceBusProcessor |
Yes |
| Session |
ServiceBusSessionProcessor.ProcessSessionMessage |
Azure.Messaging.ServiceBus.ServiceBusSessionProcessor |
No |
Because the host has no listener for the session ActivitySource:
- The SDK's
DiagnosticScope.Start() calls ActivitySource.StartActivity() which returns null (no listeners)
Activity.Current remains null when the function is invoked
ActivitySourceWrapper (source) sees Activity.Current == null and creates a root activity → new OperationId/trace
Reproduction
- Create two Azure Functions (isolated worker, .NET):
- Function A (HTTP trigger): Sends a message to a session-enabled Service Bus queue
- Function B (Service Bus trigger with
IsSessionsEnabled = true): Receives and processes the message
- Configure
host.json with "telemetryMode": "OpenTelemetry"
- Configure OpenTelemetry with Azure Monitor exporter in both functions
- Send a request to Function A
- Observe in Application Insights that Function A and Function B have different Operation IDs
If you repeat the same test with sessions disabled (IsSessionsEnabled = false), Function A and Function B share the same Operation Id.
Expected Behavior
Session-enabled Service Bus triggers should propagate the W3C trace context from the message, maintaining the same Operation Id across the distributed trace — identical to non-session triggers.
Proposed Fix
Add the missing ActivitySource name to OpenTelemetryConstants.cs:
internal static class ActivitySourceNames
{
internal const string WebJobs = "Microsoft.Azure.WebJobs";
internal const string Host = "Microsoft.Azure.Functions.Host";
internal const string ServiceBusProcessor = "Azure.Messaging.ServiceBus.ServiceBusProcessor";
+ internal const string ServiceBusSessionProcessor = "Azure.Messaging.ServiceBus.ServiceBusSessionProcessor";
internal const string EventHubsProcessor = "Azure.Messaging.EventHubs.EventProcessor";
// ...
}
And subscribe to it in OpenTelemetryConfigurationExtensions.ConfigureTracing():
ReadOnlySpan<string> sources =
[
OpenTelemetryConstants.ActivitySourceNames.ServiceBusProcessor,
+ OpenTelemetryConstants.ActivitySourceNames.ServiceBusSessionProcessor,
OpenTelemetryConstants.ActivitySourceNames.EventHubsProcessor,
// ...
];
Environment
- Azure Functions Host: 4.x (confirmed against
dev branch as of 2025-07-15)
- Azure.Messaging.ServiceBus: 7.20.1
- Microsoft.Azure.Functions.Worker.Extensions.ServiceBus: 5.24.0
- Microsoft.Azure.Functions.Worker.OpenTelemetry: 1.1.0
- .NET: 10
- Worker model: Isolated
W3C trace context not propagated for session-enabled Service Bus triggers (OpenTelemetry)
Description
When using OpenTelemetry (
"telemetryMode": "OpenTelemetry"in host.json) with session-enabled Service Bus triggers (IsSessionsEnabled = true), the W3C trace context (traceparent/tracestate) embedded in the Service Bus message is not used as the parent trace. Instead, the Functions host creates a new root activity, breaking distributed tracing across process boundaries.Non-session Service Bus triggers propagate trace context correctly. The issue is specific to session-enabled triggers.
Root Cause
The Functions host subscribes to a hardcoded list of ActivitySource names in
OpenTelemetryConfigurationExtensions.ConfigureTracing():The list includes
"Azure.Messaging.ServiceBus.ServiceBusProcessor"but is missing"Azure.Messaging.ServiceBus.ServiceBusSessionProcessor".The Azure.Messaging.ServiceBus SDK's
DiagnosticScopeFactory.GetActivitySource()(source) constructs ActivitySource names dynamically from the operation name:Combined with
DiagnosticProperty.cs(source):ServiceBusProcessor.ProcessMessageAzure.Messaging.ServiceBus.ServiceBusProcessorServiceBusSessionProcessor.ProcessSessionMessageAzure.Messaging.ServiceBus.ServiceBusSessionProcessorBecause the host has no listener for the session ActivitySource:
DiagnosticScope.Start()callsActivitySource.StartActivity()which returnsnull(no listeners)Activity.Currentremainsnullwhen the function is invokedActivitySourceWrapper(source) seesActivity.Current == nulland creates a root activity → new OperationId/traceReproduction
IsSessionsEnabled = true): Receives and processes the messagehost.jsonwith"telemetryMode": "OpenTelemetry"If you repeat the same test with sessions disabled (
IsSessionsEnabled = false), Function A and Function B share the same Operation Id.Expected Behavior
Session-enabled Service Bus triggers should propagate the W3C trace context from the message, maintaining the same Operation Id across the distributed trace — identical to non-session triggers.
Proposed Fix
Add the missing ActivitySource name to
OpenTelemetryConstants.cs:And subscribe to it in
OpenTelemetryConfigurationExtensions.ConfigureTracing():Environment
devbranch as of 2025-07-15)