-
-
Notifications
You must be signed in to change notification settings - Fork 229
Description
Package
Sentry.Azure.Functions.Worker
.NET Flavor
.NET Core
.NET Version
10.0.103
OS
No response
OS Version
No response
Development Environment
Rider 2025.x (Windows)
Other Error Monitoring Solution
No
Other Error Monitoring Solution Name
No response
SDK Version
5.16.2
Self-Hosted Sentry Version
No response
Workload Versions
Workload version: 10.0.100-manifests.c992be6d
Installed Workload Id Manifest Version Installation Source
android 36.1.2/10.0.100 VS 18.3.11512.155, VS 17.14.37012.4
ios 26.2.10191/10.0.100 VS 18.3.11512.155, VS 17.14.37012.4
maccatalyst 26.2.10191/10.0.100 VS 18.3.11512.155, VS 17.14.37012.4
maui-windows 10.0.20/10.0.100 VS 18.3.11512.155, VS 17.14.37012.4
UseSentry or SentrySdk.Init call
// Program.cs
new HostBuilder()
.ConfigureFunctionsWorkerDefaults((context, builder) =>
{
builder.UseSentry(context, options =>
{
options.Dsn = "...";
options.TracesSampleRate = 1.0;
});
})
.Build();
Steps to Reproduce
SentryFunctionsWorkerMiddleware.StartOrContinueTraceAsync only extracts sentry-trace and baggage headers from HttpRequestData. For non-HTTP triggers it passes null to ContinueTrace, generating a new trace every time:
// Decompiled from SentryFunctionsWorkerMiddleware
private async Task<TransactionContext> StartOrContinueTraceAsync(FunctionContext context)
{
string transactionName = context.FunctionDefinition.Name;
HttpRequestData val = await context.GetHttpRequestDataAsync();
if (val == null) // ← all non-HTTP triggers
{
return _hub.ContinueTrace(null, null, transactionName, "function");
}
// ... HTTP-only trace propagation
}
Then Invoke forces this new transaction onto the scope:
_hub.ConfigureScope(scope => { scope.Transaction = transaction; });
This makes it impossible for user-defined middleware to continue a trace from a queue message, because SentryFunctionsWorkerMiddleware always overwrites scope.Transaction.
Steps:
- Azure Function A (timer trigger) sends a message to a Storage Queue, including sentry-trace and baggage headers in the message body
- Azure Function B (queue trigger) receives the message
- Custom middleware on Function B reads sentry-trace/baggage from the message, calls SentrySdk.ContinueTrace() and StartTransaction()
- SentryFunctionsWorkerMiddleware overwrites scope.Transaction with a new trace
Workaround: In custom middleware running after UseSentry(), override the scope:
SentrySdk.ConfigureScope(scope => scope.Transaction = transaction);
This works but produces ghost transactions from SentryFunctionsWorkerMiddleware that cannot be suppressed (IsSampled has internal setter).
Suggested fix: StartOrContinueTraceAsync could accept trace context from non-HTTP sources via a pluggable extraction mechanism, or at minimum not overwrite scope.Transaction when it has already been set by user middleware.
Expected Result
Queue consumer function should be able to continue the trace from the producer. The sentry-trace and baggage values propagated through the queue message should be respected.
Actual Result
Every non-HTTP function invocation gets a new trace ID, breaking distributed tracing across queue-based workflows. User middleware cannot override this because SentryFunctionsWorkerMiddleware forces its own transaction onto the scope.
Metadata
Metadata
Assignees
Labels
Projects
Status