Skip to content

[bug] Race condition in Tracer.StartSpan() can throw System.InvalidOperation #6257

Open
@gwest

Description

@gwest

Package

OpenTelemetry.Api

Package Version

Package Name Version
OpenTelemetry.Api 1.11.2
OpenTelemetry 1.11.2

Runtime Version

net9.0

Description

If calling Tracer.StartSpan() when Activity.Current has an item it is possible to hit the exception:

System.InvalidOperationException: 'Trying to set an Activity that is not running'

Currently, the Tracer.StartSpan() method does the following:

  1. Captures the current Activity that is in Activity.Current as previousActivty.
  2. Creates the new TelemetrySpan to be returned.
  3. Puts previousActivity back into place as Activity.Current.

When trying to put previousActivity back into Activity.Current, if previousActivity has stopped whilst we were creating the new TelemetrySpan it will throw an error.

A simple way to avoid this seems to be by changing the following:

if (startSpanBehavior.HasFlag(StartSpanBehaviors.DeactivateNewSpan)
    && Activity.Current != previousActivity)
{
    Activity.Current = previousActivity;
}

to

if (startSpanBehavior.HasFlag(StartSpanBehaviors.DeactivateNewSpan)
    && Activity.Current != previousActivity)
{
    Activity.Current = previousActivity?.IsStopped == true ? null : previousActivity;
}

Steps to Reproduce

I've had difficulty recreating this race condition in a simple sample project.

Expected Result

No exceptions are thrown.

Actual Result

The following exception can sometimes be thrown.
System.InvalidOperationException: 'Trying to set an Activity that is not running'

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds-triageNew issues which have not been classified or triaged by a community memberpkg:OpenTelemetry.ApiIssues related to OpenTelemetry.Api NuGet package

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions