From 26bbd27347f1e9846e1323a9f368d6804f97cb33 Mon Sep 17 00:00:00 2001 From: Martin Linzmayer Date: Fri, 30 Jan 2026 17:44:15 +0530 Subject: [PATCH] fix(tracing): ignore baggage sample rate if sentry trace is not present --- src/Tracing/Traits/TraceHeaderParserTrait.php | 17 ++++++++--------- tests/State/HubTest.php | 16 ++++++++++++++++ tests/Tracing/TransactionContextTest.php | 7 +++++++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Tracing/Traits/TraceHeaderParserTrait.php b/src/Tracing/Traits/TraceHeaderParserTrait.php index 56e002d68..e1c1754eb 100644 --- a/src/Tracing/Traits/TraceHeaderParserTrait.php +++ b/src/Tracing/Traits/TraceHeaderParserTrait.php @@ -65,22 +65,21 @@ protected static function parseTraceAndBaggageHeaders(string $sentryTrace, strin $samplingContext = DynamicSamplingContext::fromHeader($baggage); - if ($hasSentryTrace && !$samplingContext->hasEntries()) { + if ($hasSentryTrace) { // The request comes from an old SDK which does not support Dynamic Sampling. // Propagate the Dynamic Sampling Context as is, but frozen, even without sentry-* entries. - $samplingContext->freeze(); - $result['dynamicSamplingContext'] = $samplingContext; - } + if (!$samplingContext->hasEntries()) { + $samplingContext->freeze(); + } - if ($hasSentryTrace && $samplingContext->hasEntries()) { // The baggage header contains Dynamic Sampling Context data from an upstream SDK. // Propagate this Dynamic Sampling Context. $result['dynamicSamplingContext'] = $samplingContext; - } - // Store the propagated traces sample rate - if ($samplingContext->has('sample_rate')) { - $result['parentSamplingRate'] = (float) $samplingContext->get('sample_rate'); + // Store the propagated traces sample rate + if ($samplingContext->has('sample_rate')) { + $result['parentSamplingRate'] = (float)$samplingContext->get('sample_rate'); + } } // Store the propagated trace sample rand or generate a new one diff --git a/tests/State/HubTest.php b/tests/State/HubTest.php index bb735cb96..fa2f17673 100644 --- a/tests/State/HubTest.php +++ b/tests/State/HubTest.php @@ -636,6 +636,22 @@ public function testStartTransactionWithTracesSampler(Options $options, Transact $this->assertSame($expectedSampled, $transaction->getSampled()); } + public function testStartTransactionIgnoresBaggageSampleRateWithoutSentryTrace(): void + { + $client = $this->createMock(ClientInterface::class); + $client->expects($this->once()) + ->method('getOptions') + ->willReturn(new Options([ + 'traces_sample_rate' => 0.0, + ])); + + $hub = new Hub($client); + $transactionContext = TransactionContext::fromHeaders('', 'sentry-sample_rate=1'); + $transaction = $hub->startTransaction($transactionContext); + + $this->assertFalse($transaction->getSampled()); + } + public static function startTransactionDataProvider(): iterable { yield 'Acceptable float value returned from traces_sampler' => [ diff --git a/tests/Tracing/TransactionContextTest.php b/tests/Tracing/TransactionContextTest.php index 93dd5bfc5..3f382d39f 100644 --- a/tests/Tracing/TransactionContextTest.php +++ b/tests/Tracing/TransactionContextTest.php @@ -149,4 +149,11 @@ public function testSampleRandRangeWhenParentNotSampledAndSampleRateProvided(): $this->assertGreaterThanOrEqual(0.4, $sampleRand); $this->assertLessThanOrEqual(0.999999, $sampleRand); } + + public function testParentSamplingRateIsIgnoredWithoutSentryTraceHeader(): void + { + $context = TransactionContext::fromHeaders('', 'sentry-sample_rate=1'); + + $this->assertNull($context->getMetadata()->getParentSamplingRate()); + } }