From 82bfc1430ee3b1902a3d4fa5f15813474912d8e1 Mon Sep 17 00:00:00 2001 From: lazerg Date: Thu, 29 Oct 2026 12:11:42 +0500 Subject: [PATCH 1/3] feat(apollo): Add a flag to stop attaching tracing headers in SentryApolloInterceptor --- CHANGELOG.md | 2 ++ sentry-apollo/api/sentry-apollo.api | 3 ++- .../io/sentry/apollo/SentryApolloInterceptor.kt | 5 ++++- .../sentry/apollo/SentryApolloInterceptorTest.kt | 15 +++++++++++++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5d16525733..002425a3bf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - Added `Environment` to the `Scope`, allowing you to overwrite the `Environment` set on the options ([#5772](https://github.com/getsentry/sentry-java/pull/5772)) - The scope `Environment` is also applied to the trace envelope header (DSC), logs, metrics and profiles, so all telemetry of a trace reports the same environment +- Add an `attachTracingHeaders` flag to `SentryApolloInterceptor` to stop attaching `sentry-trace` and `baggage` headers to Apollo v2 requests + - Apollo v2 has no request URL in the interceptor, so these headers are attached without checking `tracePropagationTargets`. Pass `attachTracingHeaders = false` to opt out. ### Fixes diff --git a/sentry-apollo/api/sentry-apollo.api b/sentry-apollo/api/sentry-apollo.api index 63eac6a1935..321d947610e 100644 --- a/sentry-apollo/api/sentry-apollo.api +++ b/sentry-apollo/api/sentry-apollo.api @@ -7,7 +7,8 @@ public final class io/sentry/apollo/SentryApolloInterceptor : com/apollographql/ public fun ()V public fun (Lio/sentry/IScopes;)V public fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V - public synthetic fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;Z)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V public fun dispose ()V public fun interceptAsync (Lcom/apollographql/apollo/interceptor/ApolloInterceptor$InterceptorRequest;Lcom/apollographql/apollo/interceptor/ApolloInterceptorChain;Ljava/util/concurrent/Executor;Lcom/apollographql/apollo/interceptor/ApolloInterceptor$CallBack;)V diff --git a/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt b/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt index 3524d32dc1f..ba1fb67b752 100644 --- a/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt +++ b/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt @@ -36,6 +36,7 @@ private const val TRACE_ORIGIN = "auto.graphql.apollo" class SentryApolloInterceptor( private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null, + private val attachTracingHeaders: Boolean = true, ) : ApolloInterceptor { private companion object { init { @@ -46,6 +47,8 @@ class SentryApolloInterceptor( constructor(scopes: IScopes) : this(scopes, null) + constructor(scopes: IScopes, beforeSpan: BeforeSpanCallback?) : this(scopes, beforeSpan, true) + constructor(beforeSpan: BeforeSpanCallback) : this(ScopesAdapter.getInstance(), beforeSpan) init { @@ -134,7 +137,7 @@ class SentryApolloInterceptor( private fun addTracingHeaders(request: InterceptorRequest, span: ISpan?): RequestHeaders { val requestHeaderBuilder = request.requestHeaders.toBuilder() - if (scopes.options.isTraceSampling && !isIgnored()) { + if (attachTracingHeaders && scopes.options.isTraceSampling && !isIgnored()) { // we have no access to URI, no way to verify tracing origins TracingUtils.trace( scopes, diff --git a/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt b/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt index 9c35f7249c2..b212e2212c8 100644 --- a/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt +++ b/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt @@ -88,6 +88,7 @@ class SentryApolloInterceptorTest { } }""", socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, + attachTracingHeaders: Boolean = true, beforeSpan: SentryApolloInterceptor.BeforeSpanCallback? = null, ): ApolloClient { server.enqueue( @@ -97,8 +98,8 @@ class SentryApolloInterceptorTest { .setResponseCode(httpStatusCode) ) - if (beforeSpan != null) { - interceptor = SentryApolloInterceptor(scopes, beforeSpan) + if (beforeSpan != null || !attachTracingHeaders) { + interceptor = SentryApolloInterceptor(scopes, beforeSpan, attachTracingHeaders) } return ApolloClient.builder() .serverUrl(server.url("/")) @@ -206,6 +207,16 @@ class SentryApolloInterceptorTest { assertNull(recorderRequest.headers[BaggageHeader.BAGGAGE_HEADER]) } + @Test + fun `does not add sentry-trace header when attaching tracing headers is disabled`() { + executeQuery(fixture.getSut(attachTracingHeaders = false)) + + val recorderRequest = + fixture.server.takeRequest(mockServerRequestTimeoutMillis, TimeUnit.MILLISECONDS)!! + assertNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER]) + assertNull(recorderRequest.headers[BaggageHeader.BAGGAGE_HEADER]) + } + @Test fun `when there is an active span, adds sentry trace headers to the request`() { executeQuery() From 62998423a2eb07a5a0ba39694fc192cbd7248733 Mon Sep 17 00:00:00 2001 From: lazerg Date: Thu, 29 Oct 2026 12:26:23 +0500 Subject: [PATCH 2/3] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 002425a3bf2..fbf8b38a3a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ - Added `Environment` to the `Scope`, allowing you to overwrite the `Environment` set on the options ([#5772](https://github.com/getsentry/sentry-java/pull/5772)) - The scope `Environment` is also applied to the trace envelope header (DSC), logs, metrics and profiles, so all telemetry of a trace reports the same environment -- Add an `attachTracingHeaders` flag to `SentryApolloInterceptor` to stop attaching `sentry-trace` and `baggage` headers to Apollo v2 requests +- Add an `attachTracingHeaders` flag to `SentryApolloInterceptor` to stop attaching `sentry-trace` and `baggage` headers to Apollo v2 requests ([#6414](https://github.com/getsentry/sentry-java/pull/6414)) - Apollo v2 has no request URL in the interceptor, so these headers are attached without checking `tracePropagationTargets`. Pass `attachTracingHeaders = false` to opt out. ### Fixes From 14abac41184c07eaf1df7edf3c8b3e2df9e2c6dc Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Thu, 29 Oct 2026 11:01:18 +0100 Subject: [PATCH 3/3] fix(apollo): Preserve interceptor constructor compatibility Keep the existing Kotlin default-argument constructor ABI while exposing the tracing-header opt-out through a secondary constructor. This prevents runtime linkage failures for precompiled consumers upgrading the SDK. Co-Authored-By: Claude --- sentry-apollo/api/sentry-apollo.api | 1 + .../java/io/sentry/apollo/SentryApolloInterceptor.kt | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sentry-apollo/api/sentry-apollo.api b/sentry-apollo/api/sentry-apollo.api index 321d947610e..0514689d3cd 100644 --- a/sentry-apollo/api/sentry-apollo.api +++ b/sentry-apollo/api/sentry-apollo.api @@ -7,6 +7,7 @@ public final class io/sentry/apollo/SentryApolloInterceptor : com/apollographql/ public fun ()V public fun (Lio/sentry/IScopes;)V public fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;Z)V public synthetic fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V diff --git a/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt b/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt index ba1fb67b752..907217bea7f 100644 --- a/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt +++ b/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt @@ -36,7 +36,6 @@ private const val TRACE_ORIGIN = "auto.graphql.apollo" class SentryApolloInterceptor( private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null, - private val attachTracingHeaders: Boolean = true, ) : ApolloInterceptor { private companion object { init { @@ -45,9 +44,17 @@ class SentryApolloInterceptor( } } + private var attachTracingHeaders: Boolean = true + constructor(scopes: IScopes) : this(scopes, null) - constructor(scopes: IScopes, beforeSpan: BeforeSpanCallback?) : this(scopes, beforeSpan, true) + constructor( + scopes: IScopes = ScopesAdapter.getInstance(), + beforeSpan: BeforeSpanCallback? = null, + attachTracingHeaders: Boolean, + ) : this(scopes, beforeSpan) { + this.attachTracingHeaders = attachTracingHeaders + } constructor(beforeSpan: BeforeSpanCallback) : this(ScopesAdapter.getInstance(), beforeSpan)