Commit 96c9c72
feat: Add strict trace continuation support (#5136)
* feat: Add strict trace continuation support
Extract org ID from DSN host, add strictTraceContinuation and orgId
options, propagate sentry-org_id in baggage, and validate incoming
traces per the decision matrix.
Closes #5128
* Format code
* Add changelog entry
* Update API surface file for strict trace continuation
Add public API declarations for new org ID and strict trace
continuation methods on Baggage, PropagationContext, and SentryOptions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address review comments for strict trace continuation
- Make Dsn.orgId final, remove unnecessary setter
- Fix test signatures to use List<String> for baggage headers
- Add strictTraceContinuation and orgId to ExternalOptions and merge()
- Add options to ManifestMetadataReader for Android manifest config
- Use Sentry.getCurrentScopes().getOptions() in legacy fromHeaders overload
- Improve CHANGELOG description with details about new options
- Update API surface file for ExternalOptions changes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix compilation errors after rebase on main
- Add comment to empty catch block in PropagationContext to satisfy -Werror
- Add setOrgId setter to Dsn class (remove final modifier on orgId field) to
support the existing test for org ID override
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: Move changelog entry to Unreleased section
* Format code
* fix: Address review comments — pass options to PropagationContext, fix OTel overload, add option tests, make Dsn.orgId final
- Remove PropagationContext.fromHeaders overload without SentryOptions; all
callers now pass options (or null) explicitly instead of relying on
Sentry.getCurrentScopes()
- Add SentryOptions parameter to the OTel-facing fromHeaders(SentryTraceHeader,
Baggage, SpanId) overload so OpenTelemetry integrations also check orgId
- Make Dsn.orgId final and remove the setter — orgId is only set during
DSN parsing in the constructor
- Add tests for strictTraceContinuation and orgId options in
ExternalOptionsTest, SentryOptionsTest, and ManifestMetadataReaderTest
- Improve CHANGELOG entry with customer-facing description
- Update API declarations (apiDump)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: Add missing 8.34.1 changelog section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Format code
* fix: Address PR review comments for strict trace continuation
- Remove duplicated org ID check in PropagationContext.fromHeaders, pass
options through to the single-check overload instead
- Add debug log when trace is not continued in the SentryTraceHeader overload
- Handle empty/blank org ID strings in shouldContinueTrace to avoid
silently breaking traces
- Update OtelSentrySpanProcessor to use PropagationContext.fromHeaders
with options for org_id validation
- Rename ExternalOptions property key to enable-strict-trace-continuation
(matching the enable- prefix convention for newer options)
- Update ExternalOptionsTest to use the new property key
- Add strict-trace-continuation and org-id properties to all 3 Spring
Boot SentryAutoConfigurationTest modules
- Improve CHANGELOG entry with detailed customer-facing descriptions
and configuration examples for all options
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Format code
* fix(tracing): Clarify strict org validation debug log
Update the trace-continuation rejection log message to cover all strict org ID validation failures, including missing org IDs, not just mismatches.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(android): Use enabled suffix for strict trace manifest key
Rename the Android manifest option to io.sentry.strict-trace-continuation.enabled to align with existing enabled-style manifest flags.
Update changelog documentation to match the new Android key.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(api): Mark effective org ID helper as internal
Annotate SentryOptions.getEffectiveOrgId with ApiStatus.Internal since it is used as an internal helper for trace propagation org ID resolution.
Co-Authored-By: Claude <noreply@anthropic.com>
* ref(tracing): Extract trace continuation decision into TracingUtils
Move strict trace continuation org-id validation logic to TracingUtils
so it can be reused by tracing entry points.
Update PropagationContext to call the shared helper and add dedicated
TracingUtils tests for strict/non-strict org-id continuation outcomes.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(opentelemetry): Enforce strict continuation in propagators
Apply strict trace continuation checks in all OpenTelemetry propagator
extract paths before creating remote parent span context.
When org-id validation fails, return the original context and ignore
incoming sentry-trace and baggage to keep propagation behavior aligned
with strict continuation requirements.
Add rejection tests for OtelSentryPropagator, deprecated
SentryPropagator, and OpenTelemetryOtlpPropagator.
Co-Authored-By: Claude <noreply@anthropic.com>
* Format code
* fix(tracing): Fix empty orgId bypassing DSN fallback
The getEffectiveOrgId() method only checked orgId != null, allowing
empty strings and whitespace-only values to bypass the DSN fallback
mechanism. This caused empty org IDs to propagate to outgoing baggage
headers as sentry-org_id=, silently breaking trace continuation in
strict mode.
Update getEffectiveOrgId() to trim the orgId value and check if it's
empty after trimming. Empty or blank values now correctly fall back
to the DSN org ID instead of propagating as empty strings.
Add comprehensive test coverage for all edge cases including empty
strings, whitespace-only values, and their impact on baggage
propagation and strict trace continuation.
Co-Authored-By: Claude <noreply@anthropic.com>
* Format code
* ref: Remove redundant trim of already-trimmed effective org ID
getEffectiveOrgId() already guarantees it returns either null or a
trimmed, non-empty string. The defensive trim and empty check in
shouldContinueTrace was dead code that could never change the result.
Co-Authored-By: Claude <noreply@anthropic.com>
* ref(tracing): Revert shouldContinueTrace check in OtelSentrySpanProcessor
The propagator is the correct enforcement point for org ID validation.
By the time the span processor runs, OTel has already created the span
with the remote parent's trace ID. If shouldContinueTrace rejects here,
it creates a fresh PropagationContext with a mismatched trace ID rather
than cleanly rejecting the trace.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(test): Clean up global Sentry state in SentryPropagatorTest
SentryPropagatorTest calls Sentry.init with strict trace continuation
but never closes Sentry afterward. This leaks global state into
SentrySpanProcessorTest where SentryPropagator uses the global
ScopesAdapter and rejects incoming sentry-trace headers under the
leaked strict mode configuration.
Add @AfterTest that calls Sentry.close() to prevent state leakage.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(test): Use mock scopes in propagator strict continuation tests
The strict continuation tests called Sentry.init with strict mode and
org ID configuration, which leaked global state into other tests.
Sentry.close() does not fully reset the global scope options, so
SentrySpanProcessorTest's SentryPropagator (using ScopesAdapter) would
reject incoming sentry-trace headers.
Use the package-private constructor with mock IScopes instead of
relying on global Sentry state for strict continuation validation.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(test): Reset OTel context in propagator test teardown
Sentry.init uses OtelContextScopesStorage which pushes scopes onto the
OTel context via makeCurrent(). The returned pop-token is discarded by
Sentry.init, and OtelContextScopesStorage.close() is a no-op, so
Sentry.close() alone does not restore the OTel context.
Since JUnit reuses the same thread across test classes, stale scopes
from SentryPropagatorTest (with strict continuation enabled) leaked
into SentrySpanProcessorTest via Context.current().
Add Context.root().makeCurrent() after Sentry.close() in all
propagator test teardowns to reset the thread-local OTel context.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(test): Add back test for inject with invalid span
The previous commit replaced the invalid-span inject test with a
no-span-in-context test. These are distinct scenarios: an explicitly
invalid span vs no span at all. Restore the invalid span test and
keep both.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Sentry Github Bot <bot+github-bot@sentry.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Alexander Dinauer <alexander.dinauer@sentry.io>
Co-authored-by: Alexander Dinauer <adinauer@users.noreply.github.com>1 parent 22ff2c7 commit 96c9c72
File tree
35 files changed
+963
-70
lines changed- sentry-android-core/src
- main/java/io/sentry/android/core
- test/java/io/sentry/android/core
- sentry-opentelemetry
- sentry-opentelemetry-core/src
- main/java/io/sentry/opentelemetry
- test/kotlin
- sentry-opentelemetry-otlp/src
- main/java/io/sentry/opentelemetry/otlp
- test/kotlin
- sentry-spring-7/src/test/kotlin/io/sentry/spring7
- tracing
- webflux
- sentry-spring-boot-4/src/test/kotlin/io/sentry/spring/boot4
- sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta
- sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot
- sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta
- tracing
- webflux
- sentry-spring/src/test/kotlin/io/sentry/spring
- tracing
- webflux
- sentry
- api
- src
- main/java/io/sentry
- util
- test/java/io/sentry
- util
35 files changed
+963
-70
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
7 | 11 | | |
8 | 12 | | |
9 | 13 | | |
| |||
Lines changed: 12 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
167 | 167 | | |
168 | 168 | | |
169 | 169 | | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
170 | 173 | | |
171 | 174 | | |
172 | 175 | | |
| |||
667 | 670 | | |
668 | 671 | | |
669 | 672 | | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
670 | 682 | | |
671 | 683 | | |
672 | 684 | | |
| |||
Lines changed: 50 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2461 | 2461 | | |
2462 | 2462 | | |
2463 | 2463 | | |
| 2464 | + | |
| 2465 | + | |
| 2466 | + | |
| 2467 | + | |
| 2468 | + | |
| 2469 | + | |
| 2470 | + | |
| 2471 | + | |
| 2472 | + | |
| 2473 | + | |
| 2474 | + | |
| 2475 | + | |
| 2476 | + | |
| 2477 | + | |
| 2478 | + | |
| 2479 | + | |
| 2480 | + | |
| 2481 | + | |
| 2482 | + | |
| 2483 | + | |
| 2484 | + | |
| 2485 | + | |
| 2486 | + | |
| 2487 | + | |
| 2488 | + | |
| 2489 | + | |
| 2490 | + | |
| 2491 | + | |
| 2492 | + | |
| 2493 | + | |
| 2494 | + | |
| 2495 | + | |
| 2496 | + | |
| 2497 | + | |
| 2498 | + | |
| 2499 | + | |
| 2500 | + | |
| 2501 | + | |
| 2502 | + | |
| 2503 | + | |
| 2504 | + | |
| 2505 | + | |
| 2506 | + | |
| 2507 | + | |
| 2508 | + | |
| 2509 | + | |
| 2510 | + | |
| 2511 | + | |
| 2512 | + | |
| 2513 | + | |
2464 | 2514 | | |
Lines changed: 8 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
116 | 124 | | |
117 | 125 | | |
118 | 126 | | |
| |||
Lines changed: 12 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
98 | 99 | | |
99 | 100 | | |
100 | 101 | | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
101 | 113 | | |
102 | 114 | | |
103 | 115 | | |
| |||
107 | 119 | | |
108 | 120 | | |
109 | 121 | | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | 122 | | |
114 | 123 | | |
115 | 124 | | |
| |||
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
| 94 | + | |
| 95 | + | |
95 | 96 | | |
96 | 97 | | |
97 | 98 | | |
| |||
Lines changed: 4 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
127 | 127 | | |
128 | 128 | | |
129 | 129 | | |
130 | | - | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
131 | 134 | | |
132 | 135 | | |
133 | 136 | | |
| |||
Lines changed: 23 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| |||
38 | 39 | | |
39 | 40 | | |
40 | 41 | | |
| 42 | + | |
| 43 | + | |
41 | 44 | | |
42 | 45 | | |
43 | 46 | | |
| |||
69 | 72 | | |
70 | 73 | | |
71 | 74 | | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
72 | 95 | | |
73 | 96 | | |
74 | 97 | | |
| |||
Lines changed: 48 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
Lines changed: 13 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
| |||
87 | 88 | | |
88 | 89 | | |
89 | 90 | | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
90 | 101 | | |
91 | 102 | | |
92 | 103 | | |
| |||
104 | 115 | | |
105 | 116 | | |
106 | 117 | | |
107 | | - | |
108 | | - | |
109 | | - | |
| 118 | + | |
| 119 | + | |
110 | 120 | | |
111 | 121 | | |
112 | 122 | | |
| |||
0 commit comments