Description
System.Diagnostics.W3CPropagator and the related Activity propagation path do not fully comply with the W3C Trace Context Level 2 test suite.
The most direct issue is in W3CPropagator.ExtractTraceIdAndState: after traceparent is missing or rejected, it still reads and validates tracestate. W3C Trace Context Level 2 says that if parsing traceparent fails, vendors must not attempt to parse tracestate.
Observed source shape:
getter(carrier, TraceParent, out traceId, out _);
if (IsInvalidTraceParent(traceId))
{
traceId = null;
}
getter(carrier, TraceState, out string? traceStateValue, out _);
traceState = ValidateTraceState(traceStateValue);
This allows a request with only tracestate to propagate tracestate into a newly generated trace context.
Running the full upstream W3C HTTP compliance suite also shows additional Level 2 failures around future-version traceparent propagation and tracestate validation.
Reproduction Steps
I added a standalone repro under:
src/tests/W3CTraceContextCompliance
The test harness is available here:
https://github.com/Kielek/runtime/commit/9f88d19ffa843faf7a29c258ac2b77795f88bea9
The repro starts a small ASP.NET Core endpoint that uses DistributedContextPropagator.CreateW3CPropagator(), then runs the embedded upstream w3c/trace-context test suite against it.
From the dotnet/runtime repository root:
pwsh -File .\src\tests\W3CTraceContextCompliance\run-w3c-suite.ps1
The runner uses:
W3C trace-context commit: 34b10ac5af7f0caeb28efe35fe51cd4763ec5771
SPEC_LEVEL=2
STRICT_LEVEL=2
Test-suite note: the embedded W3C commit above contains tracestate key grammar expectations that were reported in w3c/trace-context#583 and corrected by w3c/trace-context#584. For validation with the corrected suite, use the PR w3c/trace-context#584 head commit:
W3C trace-context PR #584 head: 6261328fd701ca967f13ca0543504db879c3b6e0
If System.Diagnostics.DiagnosticSource is already built:
pwsh -File .\src\tests\W3CTraceContextCompliance\run-w3c-suite.ps1 `
-SkipDiagnosticSourceBuild
Expected behavior
The W3C Trace Context Level 2 suite should pass.
In particular:
tracestate should be ignored when traceparent is missing or invalid.
- Valid future-version
traceparent values should be accepted according to the forward-compatibility rules.
- Invalid
tracestate values should not be propagated.
- Valid
tracestate values with Level 2 key/member/OWS rules should be preserved.
Actual behavior
The full suite runs, but fails:
STRICT_LEVEL: 2
SPEC_LEVEL: 2
harness listening on http://127.0.0.1:7777
Ran 41 tests in 0.978s
FAILED (failures=5, errors=2)
W3C suite exit code: 7
Failing tests:
FAIL test_traceparent_version_0xCC
FAIL test_tracestate_included_traceparent_missing
ERROR test_tracestate_key_illegal_characters
ERROR test_tracestate_key_illegal_vendor_format
FAIL test_tracestate_key_length_limit
FAIL test_tracestate_member_count_limit
FAIL test_tracestate_ows_handling
The test_tracestate_key_illegal_vendor_format and part of test_tracestate_key_length_limit failures are affected by the W3C suite grammar issue tracked by w3c/trace-context#583 and fixed in w3c/trace-context#584. The remaining failures are runtime behavior issues independent of that test-suite correction.
The focused ExtractTraceIdAndState behavior can be reduced to:
missing traceparent + tracestate=foo=1
expected: traceId=null, traceState=null
actual: traceId=null, traceState=foo=1
and:
invalid traceparent + tracestate=foo=1
expected: traceId=null, traceState=null
actual: traceId=null, traceState=foo=1
Regression?
Probably no, IMO still worth to include into .NET 11.
Known Workarounds
N/ACallers can manually discard the returned traceState whenever traceId is null, but that does not fix the built-in propagator behavior or the HTTP propagation path.
Configuration
Observed locally with:
Repository: dotnet/runtime
Target framework: net11.0
OS: Windows 10.0.26200
Architecture: x64
.NET SDK: 11.0.100-preview.5.26227.104
W3C trace-context suite commit: 34b10ac5af7f0caeb28efe35fe51cd4763ec5771
Python: 3.11 venv with the pinned OpenTelemetry W3C test requirements
Other information
Reported w3c/trace-context#583 and proposed fix w3c/trace-context#584 under W3C.
Description
System.Diagnostics.W3CPropagatorand the relatedActivitypropagation path do not fully comply with the W3C Trace Context Level 2 test suite.The most direct issue is in
W3CPropagator.ExtractTraceIdAndState: aftertraceparentis missing or rejected, it still reads and validatestracestate. W3C Trace Context Level 2 says that if parsingtraceparentfails, vendors must not attempt to parsetracestate.Observed source shape:
This allows a request with only
tracestateto propagatetracestateinto a newly generated trace context.Running the full upstream W3C HTTP compliance suite also shows additional Level 2 failures around future-version
traceparentpropagation andtracestatevalidation.Reproduction Steps
I added a standalone repro under:
The test harness is available here:
The repro starts a small ASP.NET Core endpoint that uses
DistributedContextPropagator.CreateW3CPropagator(), then runs the embedded upstreamw3c/trace-contexttest suite against it.From the dotnet/runtime repository root:
The runner uses:
Test-suite note: the embedded W3C commit above contains tracestate key grammar expectations that were reported in w3c/trace-context#583 and corrected by w3c/trace-context#584. For validation with the corrected suite, use the PR w3c/trace-context#584 head commit:
If
System.Diagnostics.DiagnosticSourceis already built:Expected behavior
The W3C Trace Context Level 2 suite should pass.
In particular:
tracestateshould be ignored whentraceparentis missing or invalid.traceparentvalues should be accepted according to the forward-compatibility rules.tracestatevalues should not be propagated.tracestatevalues with Level 2 key/member/OWS rules should be preserved.Actual behavior
The full suite runs, but fails:
Failing tests:
The
test_tracestate_key_illegal_vendor_formatand part oftest_tracestate_key_length_limitfailures are affected by the W3C suite grammar issue tracked by w3c/trace-context#583 and fixed in w3c/trace-context#584. The remaining failures are runtime behavior issues independent of that test-suite correction.The focused
ExtractTraceIdAndStatebehavior can be reduced to:and:
Regression?
Probably no, IMO still worth to include into .NET 11.
Known Workarounds
N/ACallers can manually discard the returned
traceStatewhenevertraceIdisnull, but that does not fix the built-in propagator behavior or the HTTP propagation path.Configuration
Observed locally with:
Other information
Reported w3c/trace-context#583 and proposed fix w3c/trace-context#584 under W3C.