Closed
Description
Is there any reason why timeouts or requests cancelled by the caller are not reported as error with native HTTP instrumentation? I tested by cancelling the request, with the built-in timeout mechanism (HttpClient.Timeout
) and Polly (Microsoft.Extensions.Http.Resilience
).
With OpenTelemetry.Instrumentation.Http
, Activity.StatusCode
and error.type
tag are set:
Activity.TraceId: 1bc0f5ddfe12988504745d22f8a57011
Activity.SpanId: 411e2d135daba899
Activity.TraceFlags: Recorded
Activity.DisplayName: GET
Activity.Kind: Client
Activity.StartTime: 2025-06-02T08:11:41.0366467Z
Activity.Duration: 00:00:00.9991566
Activity.Tags:
http.request.method: GET
server.address: httpstat.us
server.port: 443
url.full: https://httpstat.us/200?sleep=5000
error.type: System.Threading.Tasks.TaskCanceledException
StatusCode: Error
Activity.StatusDescription: Task Canceled
Instrumentation scope (ActivitySource):
Name: System.Net.Http
Resource associated with Activity:
service.name: basket-api
host.name: 2d2c402928e7
deployment.environment: Development
With native instrumentation (manually with ActivityListener
or TracerProviderBuilder.AddSource("System.Net.Http")
), the span is considered successful as Activity.StatusCode
is not set:
Activity.TraceId: 3b94dc1bacb7925e2d06b0255c3a2d64
Activity.SpanId: 7404392518785446
Activity.TraceFlags: Recorded
Activity.DisplayName: GET
Activity.Kind: Client
Activity.StartTime: 2025-06-02T08:15:36.9133316Z
Activity.Duration: 00:00:01.0040950
Activity.Tags:
http.request.method: GET
server.address: httpstat.us
server.port: 443
url.full: https://httpstat.us/200?sleep=5000
Instrumentation scope (ActivitySource):
Name: System.Net.Http
Resource associated with Activity:
service.name: basket-api
host.name: e2e40c7ea562
deployment.environment: Development
Looks like this behavior is coming from:
where OperationCanceledException
are treated differently and not captured. The finally
block doesn't set the error in this case.