Skip to content

Fix baggage header merging and networkContext propagation in TracingURLSessionHandler#2683

Open
Valpertui wants to merge 5 commits into
developfrom
valpertui/fix/missing-baggage-merge-in-tracing
Open

Fix baggage header merging and networkContext propagation in TracingURLSessionHandler#2683
Valpertui wants to merge 5 commits into
developfrom
valpertui/fix/missing-baggage-merge-in-tracing

Conversation

@Valpertui
Copy link
Copy Markdown
Member

What and why?

TracingURLSessionHandler.modify() had two issues:

  1. W3C baggage headers were not merged — when a request already had a baggage header, the handler skipped it entirely (same "do not overwrite" logic as trace propagation headers). Baggage headers should be merged instead, combining existing user-set values with SDK-injected ones (session.id, user.id, account.id).

  2. networkContext parameter was ignored — the modify() method accepted a NetworkContext? parameter but never used it for populating rumSessionId, userId, and accountId in the TraceContext. It read exclusively from contextReceiver.context, so values provided via networkContext were never propagated into baggage headers.

How?

  • Move BaggageHeaderMerger from DatadogRUM to DatadogInternal so it can be used by TracingURLSessionHandler.
  • Add baggage header merging in modify(): when a writer produces a baggage header, merge it with any existing value using BaggageHeaderMerger instead of skipping.
  • Use networkContext as the primary source for rumSessionId, userId, and accountId when creating the TraceContext, falling back to contextReceiver.context.

Review checklist

  • Feature or bugfix MUST have appropriate tests (unit, integration)
  • Make sure each commit and the PR mention the Issue number or JIRA reference
  • Add CHANGELOG entry for user facing changes
  • Add Objective-C interface for public APIs - see our guidelines (internal)
  • Run make api-surface when adding new APIs

@Valpertui Valpertui requested a review from a team as a code owner February 6, 2026 21:25
@Valpertui Valpertui force-pushed the valpertui/fix/missing-baggage-merge-in-tracing branch from 20320e8 to 21e6420 Compare February 6, 2026 21:25
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 21e6420a28

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +112 to 116
request.setValue(mergedValue, forHTTPHeaderField: field)
} else {
request.setValue(value, forHTTPHeaderField: field)
}
hasSetAnyHeader = true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don’t return TraceContext when only baggage is injected

When a request already has W3C traceparent/tracestate set by the caller, this branch still sets hasSetAnyHeader = true after merging (or adding) baggage. That causes modify() to return a TraceContext, which NetworkInstrumentationFeature registers and later uses to build spans. The outgoing request keeps the caller’s original trace headers, so the span created from the returned TraceContext can end up on a different trace ID than the actual request, breaking distributed trace correlation whenever the app supplies its own trace headers but expects the SDK to only merge baggage. Consider tracking “trace header injected” separately from “baggage injected,” or avoid returning TraceContext when only baggage was modified.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

@Valpertui Valpertui Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is normal that there is a trace context returned if we inject any header.
But currently if at least 1 header doesn't get overwritten because it's already there (eg traceparent), we will propagate a traceContext with traceID and spanID set back to the SDK. While the network request sent will not contain those specific traceID/spanID, breaking distributed tracing in an unexpected way.

Sure it looks like a developer mistake to fix. But we need to remember that those header fields could also be set automatically by other integrations like Datadog.

Should we keep the current behavior? Should we revamp it ?

@Valpertui Valpertui force-pushed the valpertui/fix/missing-baggage-merge-in-tracing branch from 793327a to f7649d3 Compare February 6, 2026 21:57
@datadog-datadog-prod-us1

This comment has been minimized.

Valpertui and others added 5 commits February 12, 2026 10:31
BaggageHeaderMerger is needed by TracingURLSessionHandler for merging
W3C baggage headers during trace context injection. Move it to
DatadogInternal so it can be used across modules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nHandler

Two changes to the modify() method:

1. Merge W3C baggage headers instead of skipping them when already
   present on the request. This uses BaggageHeaderMerger to combine
   existing baggage values with SDK-injected ones (session.id, user.id,
   account.id), with new values taking precedence.

2. Use the networkContext parameter for populating rumSessionId, userId,
   and accountId in the TraceContext, falling back to
   contextReceiver.context. Previously networkContext was accepted but
   ignored, so these values were never propagated into baggage headers
   when provided via networkContext.

The traceContext nil assertion in the "does not overwrite headers" test
was removed because the presence of a returned traceContext depends on
whether any header was set (e.g. baggage), which is unrelated to the
non-overwriting behavior that test verifies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Valpertui Valpertui force-pushed the valpertui/fix/missing-baggage-merge-in-tracing branch from f7649d3 to 86d019d Compare February 12, 2026 13:33
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.

1 participant