From fa90117ea569a564c4c2b1b319486bf1caf7be0a Mon Sep 17 00:00:00 2001 From: Rachel Yang Date: Wed, 24 Jun 2026 12:20:02 -0400 Subject: [PATCH 1/3] test(parametric): add baggage span tags test for no-trace-context scenario MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds test_baggage_span_tags_no_trace_context to verify that baggage tags are applied to the local root span even when no upstream trace context (x-datadog-* or traceparent) is present — scenario 2 from the baggage RFC. Marks the test as missing_feature for golang, rust, dotnet, and cpp, consistent with the existing baggage span tag tests for those libraries. Co-Authored-By: Claude Sonnet 4.6 --- manifests/cpp.yml | 1 + manifests/dotnet.yml | 1 + manifests/golang.yml | 1 + manifests/rust.yml | 1 + tests/parametric/test_headers_baggage.py | 16 ++++++++++++++++ 5 files changed, 20 insertions(+) diff --git a/manifests/cpp.yml b/manifests/cpp.yml index be897f0171c..41fad9e0546 100644 --- a/manifests/cpp.yml +++ b/manifests/cpp.yml @@ -124,6 +124,7 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_config_with_empty_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_default: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_key_with_asterisk: missing_feature # Created by easy win activation script + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_specific_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_datadog.py::Test_Headers_Datadog: ">1.0.0" tests/parametric/test_headers_none.py::Test_Headers_None: ">1.0.0" diff --git a/manifests/dotnet.yml b/manifests/dotnet.yml index 64fc49e17ef..00a206e0078 100644 --- a/manifests/dotnet.yml +++ b/manifests/dotnet.yml @@ -853,6 +853,7 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_config_with_empty_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_default: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_key_with_asterisk: missing_feature # Created by easy win activation script + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_specific_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_opm.py: missing_feature (Org Propagation Guard RFC not yet implemented) ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext diff --git a/manifests/golang.yml b/manifests/golang.yml index 6e892e65203..ad2b788b802 100644 --- a/manifests/golang.yml +++ b/manifests/golang.yml @@ -1125,6 +1125,7 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_config_with_empty_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_default: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_key_with_asterisk: missing_feature # Created by easy win activation script + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_specific_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_opm.py: missing_feature (Org Propagation Guard RFC not yet implemented) ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext diff --git a/manifests/rust.yml b/manifests/rust.yml index cc3c7eca321..23346feaad3 100644 --- a/manifests/rust.yml +++ b/manifests/rust.yml @@ -145,6 +145,7 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_config_with_empty_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_default: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_key_with_asterisk: missing_feature # Created by easy win activation script + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_specific_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_datadog.py::Test_Headers_Datadog: v0.0.1 tests/parametric/test_headers_none.py::Test_Headers_None: v0.0.1 diff --git a/tests/parametric/test_headers_baggage.py b/tests/parametric/test_headers_baggage.py index 6796fef5d98..a0b51d26a79 100644 --- a/tests/parametric/test_headers_baggage.py +++ b/tests/parametric/test_headers_baggage.py @@ -426,3 +426,19 @@ def test_baggage_span_tags_config_with_empty_keys(self, test_agent: TestAgentAPI assert meta.get("baggage.account.id") == "12345" assert meta.get("baggage.foo") is None assert meta.get("baggage.test") is None + + def test_baggage_span_tags_no_trace_context(self, test_agent: TestAgentAPI, test_library: APMLibrary) -> None: + """Baggage span tags must be applied to a local root span even when no upstream trace context is present. + A request that carries only a baggage header (no x-datadog-* or traceparent headers) still creates a + local root span, and that span must receive the configured baggage tags.""" + with test_library: + _ = test_library.dd_make_child_span_and_get_headers( + [("baggage", "user.id=doggo,session.id=mysession,foo=bar")] + ) + + span = find_only_span(test_agent.wait_for_num_traces(1)) + meta = span.get("meta") + assert meta is not None + assert meta.get("baggage.user.id") == "doggo" + assert meta.get("baggage.session.id") == "mysession" + assert meta.get("baggage.foo") is None From 27f99b8e9c8a96334f73f71fbeae363e553ae7b6 Mon Sep 17 00:00:00 2001 From: Rachel Yang Date: Thu, 25 Jun 2026 11:20:03 -0400 Subject: [PATCH 2/3] test(parametric): mark baggage-no-trace-context test missing_feature for java/nodejs/php/ruby Java's parametric server drops baggage-only extraction (span_id null when no trace context). PHP, Ruby, and Node.js parametric servers have the same issue. The actual tracers for PHP and Ruby handle scenario 2 correctly, but their parametric servers need fixes first. Co-Authored-By: Claude Sonnet 4.6 --- manifests/java.yml | 1 + manifests/nodejs.yml | 1 + manifests/php.yml | 1 + manifests/ruby.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/manifests/java.yml b/manifests/java.yml index 9dbaf7c8dba..5815b328f54 100644 --- a/manifests/java.yml +++ b/manifests/java.yml @@ -3735,6 +3735,7 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_headers_baggage_default_D001: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_headers_baggage_only_D002: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags: v1.54.0-SNAPSHOT+c2aec92b86 + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_opm.py: v1.64.0-SNAPSHOT ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext : - declaration: missing_feature (Implemented from 1.24.0) diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index 72c33567235..1052c275cd8 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -2059,6 +2059,7 @@ manifest: tests/parametric/test_headers_b3.py::Test_Headers_B3::test_headers_b3_migrated_single_key_propagate_valid: missing_feature (Need to remove b3=b3multi alias) tests/parametric/test_headers_baggage.py::Test_Headers_Baggage: irrelevant (uses weblog tests) tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags: *ref_5_54_0 + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_opm.py: missing_feature (Org Propagation Guard RFC not yet implemented) ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext : - declaration: missing_feature (Implemented in 4.20.0 (and 3.41.0)) diff --git a/manifests/php.yml b/manifests/php.yml index d821d9654ef..b4f27ac0d7a 100644 --- a/manifests/php.yml +++ b/manifests/php.yml @@ -778,6 +778,7 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_baggageheader_maxitems_inject_D016: missing_feature tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_headers_baggage_only_D002: missing_feature tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags: v1.13.0+4663b2fa7c20c6920f347d059b57dc2a419cb7f7 + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_opm.py: missing_feature (Org Propagation Guard RFC not yet implemented) ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext : - declaration: missing_feature (Default value was updated in v0.98.0 (w3c phase 2)) diff --git a/manifests/ruby.yml b/manifests/ruby.yml index 9728724dcdc..1eabe1b626b 100644 --- a/manifests/ruby.yml +++ b/manifests/ruby.yml @@ -2180,6 +2180,7 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_baggageheader_maxitems_inject_D016: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_headers_baggage_only_D002: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags: v2.22.1-dev + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_opm.py: missing_feature (Org Propagation Guard RFC not yet implemented) ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext : - declaration: missing_feature (Implemented from 1.17.0) From 4ab35ce91ad2797b9a6b22b0b878dca20b516ccf Mon Sep 17 00:00:00 2001 From: Rachel Yang Date: Thu, 25 Jun 2026 11:30:09 -0400 Subject: [PATCH 3/3] fix(parametric): handle baggage-only extraction in PHP and Ruby servers PHP and Ruby tracers already apply baggage tags independently of trace context, but their parametric servers were dropping the extracted context when no trace span ID was present. PHP: add an elseif branch for the empty-string key (PHP coerces null array keys to "") so consume_distributed_tracing_headers is called even when no upstream span ID was extracted. Ruby: check DD_DIGEST[nil] before the active-span short-circuit so a baggage-only digest is passed as continue_from when parent_id is nil. Removes missing_feature for php and ruby. Go remains missing_feature because its tracer applies baggage tags only in the httptrace middleware, not in the core tracer.StartSpan path used by the parametric server. Co-Authored-By: Claude Sonnet 4.6 --- manifests/golang.yml | 2 +- manifests/php.yml | 1 - manifests/ruby.yml | 1 - utils/build/docker/php/parametric/server.php | 5 +++++ utils/build/docker/ruby/parametric/server.rb | 8 +++++++- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/manifests/golang.yml b/manifests/golang.yml index ad2b788b802..5f943d67e3c 100644 --- a/manifests/golang.yml +++ b/manifests/golang.yml @@ -1125,7 +1125,7 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_config_with_empty_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_default: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_key_with_asterisk: missing_feature # Created by easy win activation script - tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature + tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature # tracer applies baggage tags only in httptrace middleware, not in core tracer.StartSpan tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_specific_keys: missing_feature # Created by easy win activation script tests/parametric/test_headers_opm.py: missing_feature (Org Propagation Guard RFC not yet implemented) ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext diff --git a/manifests/php.yml b/manifests/php.yml index b4f27ac0d7a..d821d9654ef 100644 --- a/manifests/php.yml +++ b/manifests/php.yml @@ -778,7 +778,6 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_baggageheader_maxitems_inject_D016: missing_feature tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_headers_baggage_only_D002: missing_feature tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags: v1.13.0+4663b2fa7c20c6920f347d059b57dc2a419cb7f7 - tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_opm.py: missing_feature (Org Propagation Guard RFC not yet implemented) ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext : - declaration: missing_feature (Default value was updated in v0.98.0 (w3c phase 2)) diff --git a/manifests/ruby.yml b/manifests/ruby.yml index 1eabe1b626b..9728724dcdc 100644 --- a/manifests/ruby.yml +++ b/manifests/ruby.yml @@ -2180,7 +2180,6 @@ manifest: tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_baggageheader_maxitems_inject_D016: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage::test_headers_baggage_only_D002: missing_feature # Created by easy win activation script tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags: v2.22.1-dev - tests/parametric/test_headers_baggage.py::Test_Headers_Baggage_Span_Tags::test_baggage_span_tags_no_trace_context: missing_feature tests/parametric/test_headers_opm.py: missing_feature (Org Propagation Guard RFC not yet implemented) ? tests/parametric/test_headers_precedence.py::Test_Headers_Precedence::test_headers_precedence_propagationstyle_default_datadog_tracecontext : - declaration: missing_feature (Implemented from 1.17.0) diff --git a/utils/build/docker/php/parametric/server.php b/utils/build/docker/php/parametric/server.php index 4d061f22409..7fe422cf8f5 100644 --- a/utils/build/docker/php/parametric/server.php +++ b/utils/build/docker/php/parametric/server.php @@ -318,6 +318,11 @@ function remappedSpanKind($spanKind) { } else { $span = \DDTrace\start_trace_span(); } + } elseif (array_key_exists('', $spansDistributedTracingHeaders)) { + // baggage-only: no upstream trace context, but consume headers so baggage tags are applied + $span = \DDTrace\start_trace_span(); + \DDTrace\consume_distributed_tracing_headers($spansDistributedTracingHeaders['']); + unset($spansDistributedTracingHeaders['']); } else { $span = \DDTrace\start_trace_span(); } diff --git a/utils/build/docker/ruby/parametric/server.rb b/utils/build/docker/ruby/parametric/server.rb index c8b8db3e3b7..c7d95d37177 100644 --- a/utils/build/docker/ruby/parametric/server.rb +++ b/utils/build/docker/ruby/parametric/server.rb @@ -1054,7 +1054,13 @@ def handle_trace_span_start(req, res) args = StartSpanArgs.new(JSON.parse(req.body.read)) # If the parent span is the active span, we don't need to create a digest, # let the tracer handle span parenting. This avoids creating a new trace chunk. - digest = unless Datadog::Tracing.active_span&.id == args.parent_id + # Special case: if parent_id is nil and a baggage-only digest exists, use it + # so that baggage tags are applied to the new root span. + digest = if args.parent_id.nil? && DD_DIGEST.key?(nil) + DD_DIGEST.delete(nil) + elsif Datadog::Tracing.active_span&.id == args.parent_id + nil + else get_digest(args.parent_id) end