Skip to content

Apply incoming trace state and baggage only with NServiceBus trace context - #7954

Merged
ramonsmits merged 3 commits into
otelfrom
otel-ambient-baggage
Oct 5, 2026
Merged

ramonsmits merged 3 commits into
otelfrom
otel-ambient-baggage

Conversation

@ramonsmits

@ramonsmits ramonsmits commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

NServiceBus now propagates tracestate and baggage from the message headers only when the message has NServiceBus trace context. NServiceBus trace context is a NServiceBus.TraceParent or traceparent header. Without it, the incoming span adopts Activity.Current as parent. The span then inherits the trace state and baggage of that activity.

Changes

  • NServiceBus always propagates baggage from the message. This includes the case where a transport SDK receive span is the parent. No supported SDK propagates baggage.
  • NServiceBus skips a baggage key that the SDK span already has. This prevents duplicate baggage on each hop when SDKs start to extract baggage.
  • NServiceBus does not propagate trace state from the message when the message starts a new trace (NServiceBus.StartNewTrace). The trace state describes the trace of the sender. The new trace has no relation to that trace.
  • ActivityFactory now starts the incoming activity before it reads the headers. Activity.Start() sets Activity.Parent, so the skip can read the parent chain of the runtime. ActivityFactory still sets the W3C id format before the start.
  • ContextPropagation.PropagateContextFromHeaders is now two methods: one for trace state and one for baggage. Each branch calls the method it needs.

Rationale

The architecture decision record (ADR) records the verified SDK behavior and the Activity.Parent behavior. This change depends on both: docs/decisions/2026-10-01-receive-side-trace-state-and-baggage-propagation.md.

Docs

…ontext

Trace state and baggage headers are only meaningful together with a trace
parent. Apply them only when the message has NServiceBus trace context.
Without it, NServiceBus has nothing to propagate. The incoming span then
inherits what an ambient activity has through the parent chain.

Baggage from the headers is always applied, also when a transport SDK
receive span is the parent. None of the supported SDKs (Azure Service Bus,
RabbitMQ, SQS) propagate baggage yet. For when they do, a key the adopted
parent already has is skipped. Activity.Baggage reads through the parent
chain, so adding it again would double the baggage on every hop.

Trace state from the headers is not applied when the message starts a new
trace. It describes the trace of the sender, which the new trace is
detached from.

Start the incoming activity before the headers are read. Activity.Start()
sets Activity.Parent, so the skip can read the parent chain of the runtime
instead of tracking the adopted parent separately. The id format is still
set to W3C before the start.

Split ContextPropagation.PropagateContextFromHeaders into a trace-state
part and a baggage part on both propagator paths. The combined method stays
for callers that need both.
The switch selects the parent Activity of the incoming span. Rename it and
update all references, tests and comments to the Activity terminology.
@ramonsmits
ramonsmits force-pushed the otel-ambient-baggage branch from 30798ae to 86cc2b3 Compare October 5, 2026 14:12
Records why NServiceBus applies trace state and baggage from the message
headers on receive only when its own trace context is present, also under
an ambient transport SDK span, and why keys the adopted parent already has
are skipped. Captures the verified SDK behavior and the Activity.Parent
mechanics the decision rests on, and the alternatives that were rejected.
@ramonsmits
ramonsmits force-pushed the otel-ambient-baggage branch from 86cc2b3 to 522c367 Compare October 5, 2026 14:39
@ramonsmits
ramonsmits merged commit 5c62d2c into otel Oct 5, 2026
4 checks passed
@ramonsmits
ramonsmits deleted the otel-ambient-baggage branch October 5, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants