Skip to content

[bug] Incompatibility between OTEL BaggagePropagator and .NET W3C Baggage Propagator #6816

@gcannata2

Description

@gcannata2

Package

OpenTelemetry

Package Version

Package Name Version
OpenTelemetry.Api 1.14.0
OpenTelemetry 1.14.0

Runtime Version

net8.0

Description

Problem Description

With the latest upgrade to OpenTelemetry 1.14.0 and System.Diagnostics.DiagnosticSource 10.0.0, we've encountered a backward incompatibility issue with baggage propagation.

Background

In version 10.0, .NET definitively abandoned the Legacy propagator (which used the Correlation-Context header) and switched by default to the W3C Baggage standard (spec), which specifies:

  • The header name is baggage
  • Key-value pairs and = can be separated by optional whitespace (OWS)

In our service chain, we rely on .NET Activity Baggage because we cannot guarantee that all services are instrumented with OTEL.

Issue

When we updated to OTEL 1.14.0, baggage propagation broke. Here's what happens:

  1. .NET propagates baggage using the baggage header with key-values separated by = and spaces (e.g., key = value)
  2. OTEL BaggagePropagator reads this header but expects key-values to be separated by = without spaces (as per OTEL spec), so it parses the spaces as part of keys and values
  3. HttpClient instrumented by OTEL injects baggage using the OTEL BaggagePropagator, which URL-encodes the baggage (via WebUtility.UrlEncode)
  4. Downstream .NET services receive a baggage header with keys and values like +key+=+value+ instead of key=value

Question

Is this behavior intentional? The W3C Baggage specification allows optional whitespace around =, so it seems the OTEL BaggagePropagator should be compatible with this.

Workaround

We've worked around this by removing the OTEL BaggagePropagator from the Propagators collection, but it seems the OTEL BaggagePropagator should handle W3C-compliant baggage headers that include spaces.

Thanks a lot!

Steps to Reproduce

Set up a Service (A) that adds some keys and values to current activity using System.Diagnostics:

 Activity.Current?.AddBaggage("correlationId", "12345");
 Activity.Current?.AddBaggage("userId", "user-abc");

either do not instrument this service with OTEL or propagate the context in a way that is not handled by OTEL (in our case, it is a YARP reverse proxy).

Service (A) calls a Service (B) which is instrumented with OTEL
Service (B) calls - via HttpClient - a Service (C)

Expected Result

Service (C) should be able to correctly read the keys from the baggage.

var correlationId = Activity.Current?.GetBaggageItem("correlationId");

Actual Result

Service (C) receive keys and values "urlencoded"

var correlationId = Activity.Current?.GetBaggageItem("+correlationId+");

Additional Context

No response

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpkg:OpenTelemetryIssues related to OpenTelemetry NuGet package

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions