Skip to content

Trace Headers Not Injected Despite firstPartyHosts Configuration #1013

@1awaleed

Description

@1awaleed

Describe the bug

Description

The Datadog React Native SDK is not injecting trace correlation headers (x-datadog-trace-id, x-datadog-parent-id, x-datadog-sampling-priority, traceparent) into HTTP requests to
backend services, despite having firstPartyHosts properly configured with propagatorTypes.

Environment

  • SDK Version: @datadog/[email protected]
  • React Native Version: 0.80.2
  • Platform(s) Tested: iOS
  • HTTP Client: Axios (via RTK Query) and native Fetch API
  • Network Inspector: Flipper / Charles Proxy

Expected Behavior

HTTP requests to domains specified in firstPartyHosts should include trace correlation headers:

  • x-datadog-trace-id
  • x-datadog-parent-id
  • x-datadog-sampling-priority
  • traceparent (W3C Trace Context)

These headers should allow the backend APM to correlate RUM sessions with backend traces.

Actual Behavior

No trace headers are being added to HTTP requests to the backend, even though:

  • ✅ RUM is tracking resources correctly
  • ✅ Resources appear in RUM dashboard
  • ✅ trackResources: true is enabled
  • ✅ resourceTracingSamplingRate: 100 is set
  • ✅ firstPartyHosts is configured with propagatorTypes
  • ✅ XHR tracking is enabled

Troubleshooting Steps Taken

  • Verified requests are going to the correct domain configured in firstPartyHosts
  • Build and restarted the app multiple times after configuration changes
  • Inspected network requests using multiple tools
  • Tested with both Axios and native Fetch API - same result
  • Verified trackResources: true is working (resources appear in RUM)
  • Set resourceTracingSamplingRate: 100 to ensure all requests are sampled
  • Tested both simplified firstPartyHosts: ['example.com'] and object format with propagatorTypes
  • Verified backend domain URL format
  • Checked that initialization completes successfully

Debug Logs

With config.verbosity = SdkVerbosity.DEBUG, the SDK logs show:

  • Initialization completes successfully
  • Resources are being tracked
  • No errors or warnings about firstPartyHosts configuration
  • No indication that trace headers are being added

Questions

  1. Is the double-initialization pattern supported? Should we use ONLY DatadogProvider.initialize() OR ONLY ?
  2. Does XHR tracking work with Axios? The SDK instruments XMLHttpRequest, but could custom Axios interceptors interfere?
  3. Is there a way to verify trace headers are being injected? Any debug logs or callback we can use to confirm header injection?

Is there something wrong with our configuration, or is this a bug in the SDK?

Any guidance would be greatly appreciated! Thank you

Reproduction steps

Configuration

Datadog Provider Setup

  import {
    DatadogProvider,
    DatadogProviderConfiguration,
    PropagatorType,
    SdkVerbosity,
    UploadFrequency,
    BatchSize,
  } from '@datadog/mobile-react-native';

  // Component wrapper configuration
  const datadogAutoInstrumentation = {
    trackErrors: true,
    trackInteractions: true,
    trackResources: true,
  };

  export function DataDogProvider({ children }) {
    const initializeDatadog = async () => {
      const config = new DatadogProviderConfiguration(
        '<CLIENT_TOKEN>',
        'prod',                // Environment
        '<RUM_APP_ID>',
        true,                  // track interactions
        true,                  // track XHR Resources
        true,                  // track Errors
      );

      // Configure firstPartyHosts with propagatorTypes
      config.firstPartyHosts = [
        {
          match: 'com.example.app',  // Actual domain: *.example.com
          propagatorTypes: [
            PropagatorType.DATADOG,
            PropagatorType.TRACECONTEXT,
          ],
        },
      ];

      config.site = 'US5';
      config.serviceName = 'mobile-app';
      config.resourceTracingSamplingRate = 100;
      config.sessionSamplingRate = 100;
      config.nativeCrashReportEnabled = true;
      config.trackFrustrations = true;

      // Debug configuration
      config.verbosity = SdkVerbosity.DEBUG;
      config.uploadFrequency = UploadFrequency.FREQUENT;
      config.batchSize = BatchSize.SMALL;

      await DatadogProvider.initialize(config);
    };

    useEffect(() => {
      initializeDatadog();
    }, []);

    return (
      <DatadogProvider configuration={datadogAutoInstrumentation}>
        {children}
      </DatadogProvider>
    );
  }

HTTP Client Setup (Axios via RTK Query)

  import axios from 'axios';

  const axiosInstance = axios.create({
    timeout: 16000,
  });

  // Axios is used for all API calls to https://api.example.com/*

  Also Tested with Fetch API

  fetch('https://api.example.com/endpoint', {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer <token>'
    }
  });
  // Still no trace headers

SDK logs

No response

Expected behavior

HTTP requests to domains specified in firstPartyHosts should include trace correlation headers:

  • x-datadog-trace-id
  • x-datadog-parent-id
  • x-datadog-sampling-priority
  • traceparent (W3C Trace Context)

Affected SDK versions

2.12.2

Latest working SDK version

2.12.2

Did you confirm if the latest SDK version fixes the bug?

Yes

Integration Methods

NPM

React Native Version

0.80.2

Package.json Contents

{
"dependencies": {
    "@datadog/mobile-react-native": "^2.12.2",
    "@datadog/mobile-react-native-webview": "^2.12.2",
    "@datadog/mobile-react-navigation": "^2.12.2",
    "@date-fns/tz": "^1.2.0",
    "@formatjs/intl": "^2.10.9",
    "@formatjs/intl-datetimeformat": "^6.15.0",
    "@formatjs/intl-getcanonicallocales": "^2.4.0",
    "@formatjs/intl-locale": "^4.1.0",
    "@formatjs/intl-numberformat": "^8.13.0",
    "@formatjs/intl-pluralrules": "^5.2.17",
    "@intercom/intercom-react-native": "^8.6.0",
    "@material-design-icons/svg": "^0.14.15",
    "@react-native-async-storage/async-storage": "^2.2.0",
    "@react-native-community/blur": "^4.4.1",
    "@react-native-community/netinfo": "^11.4.1",
    "@react-native/new-app-screen": "0.80.2",
    "@react-navigation/bottom-tabs": "^7.4.4",
    "@react-navigation/native": "^7.1.16",
    "@react-navigation/stack": "^7.4.4",
    "@reduxjs/toolkit": "^2.8.2",
    "@segment/analytics-react-native": "^2.21.0",
    "@segment/sovran-react-native": "^1.1.3",
    "@transifex/cli": "^7.1.4",
    "@transifex/native": "^7.1.4",
    "@transifex/react": "^7.1.4",
    "axios": "^1.11.0",
    "configcat-react": "^4.9.0",
    "currency-symbol-map": "^5.1.0",
    "d3": "^7.9.0",
    "date-fns": "^4.1.0",
    "eventemitter3": "^5.0.1",
    "react": "19.1.0",
    "react-native": "^0.80.2",
    "react-native-app-auth": "^8.0.0",
    "react-native-collapsible": "^1.6.2",
    "react-native-device-info": "^14.0.4",
    "react-native-gesture-handler": "^2.27.2",
    "react-native-get-random-values": "^1.11.0",
    "react-native-keychain": "^10.0.0",
    "react-native-localize": "^3.5.1",
    "react-native-permissions": "^5.4.2",
    "react-native-reanimated": "^3.19.0",
    "react-native-restart": "^0.0.27",
    "react-native-safe-area-context": "^5.5.2",
    "react-native-screens": "^4.13.1",
    "react-native-segmented-control-tab": "^4.0.0",
    "react-native-svg": "^15.12.0",
    "react-native-toast-message": "^2.3.3",
    "react-native-ultimate-config": "^6.0.1",
    "react-native-url-polyfill": "^2.0.0",
    "react-native-webview": "^13.15.0",
    "react-redux": "^9.2.0",
    "redux": "^5.0.0",
    "redux-persist": "^6.0.0",
    "redux-thunk": "^3.1.0",
    "style-dictionary": "^4.1.4",
    "uuid": "^11.0.3",
    "whatwg-fetch": "^3.6.20"
  },
  "devDependencies": {
    "@babel/core": "^7.28.0",
    "@babel/plugin-transform-private-methods": "^7.27.1",
    "@babel/preset-env": "^7.28.0",
    "@babel/runtime": "^7.28.2",
    "@datadog/datadog-ci": "^3.22.2",
    "@react-native-community/cli": "19.1.1",
    "@react-native-community/cli-platform-android": "19.1.1",
    "@react-native-community/cli-platform-ios": "19.1.1",
    "@react-native/babel-preset": "0.80.2",
    "@react-native/eslint-config": "0.80.2",
    "@react-native/metro-config": "0.80.2",
    "@react-native/typescript-config": "0.80.2",
    "@redux-devtools/remote": "^0.9.5",
    "@rnx-kit/align-deps": "^3.1.0",
    "@rtk-query/codegen-openapi": "^1.2.0",
    "@testing-library/react-native": "^12.7.2",
    "@types/d3": "^7.4.3",
    "@types/d3-scale": "^4.0.9",
    "@types/jest": "^29.5.13",
    "@types/lodash.debounce": "^4.0.9",
    "@types/react": "^19.1.8",
    "@types/react-test-renderer": "^19.1.0",
    "axios-mock-adapter": "^1.22.0",
    "babel-plugin-module-resolver": "^5.0.2",
    "detox": "^20.40.2",
    "dotenv-cli": "^7.4.2",
    "eslint": "^8.57.0",
    "eslint-plugin-detox": "^1.0.0",
    "eslint-plugin-import": "^2.32.0",
    "eslint-plugin-import-alias": "^1.2.0",
    "eslint-plugin-index": "^1.1.7",
    "eslint-plugin-prettier": "^5.5.3",
    "eslint-plugin-react-compiler": "^19.1.0-rc.2",
    "eslint-plugin-react-hooks": "^5.2.0",
    "eslint-plugin-testing-library": "^6.2.2",
    "eslint-plugin-unused-imports": "^4.1.4",
    "husky": "^9.1.7",
    "jest": "^29.6.3",
    "lint-staged": "^15.2.2",
    "merge-anything": "^5.1.7",
    "patch-package": "^8.0.0",
    "prettier": "^3.5.3",
    "react-native-svg-transformer": "^1.5.1",
    "react-test-renderer": "19.1.0",
    "ts-jest": "^29.4.0",
    "type-fest": "^4.41.0",
    "typescript": "^5.4.5"
  },
  "engines": {
    "node": ">=18.12"
  },
}

iOS Setup


def node_require(script)
  # Resolve script with node to allow for hoisting
  require Pod::Executable.execute_command('node', ['-p',
    "require.resolve(
      '#{script}',
      {paths: [process.argv[1]]},
    )", __dir__]).strip
end
  
# Use it to require both react-native's and this package's scripts:
node_require('react-native/scripts/react_native_pods.rb')
node_require('react-native-permissions/scripts/setup.rb')

require 'xcodeproj'

project_path = './project.xcodeproj'
project = Xcodeproj::Project.open(project_path)
min_ios_version_supported = project.build_configurations.first.build_settings['IPHONEOS_DEPLOYMENT_TARGET']

platform :ios, min_ios_version_supported
prepare_react_native_project!

# Complete list of available permissions are listed here so we can just uncomment the ones we need
setup_permissions([
  # 'AppTrackingTransparency',
  # 'Bluetooth',
  # 'Calendars',
  # 'CalendarsWriteOnly',
  'Camera',
  # 'Contacts',
  # 'FaceID',
  # 'LocationAccuracy',
  # 'LocationAlways',
  # 'LocationWhenInUse',
  # 'MediaLibrary',
  # 'Microphone',
  # 'Motion',
  # 'Notifications',
  # 'PhotoLibrary',
  # 'PhotoLibraryAddOnly',
  # 'Reminders',
  # 'Siri',
  # 'SpeechRecognition',
  # 'StoreKit',
])

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

target 'project' do
  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  post_install do |installer|
    # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false,
      # :ccache_enabled => true
    )
  end
end

Android Setup

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "35.0.0"
        minSdkVersion = 24
        compileSdkVersion = 35
        targetSdkVersion = 35
        ndkVersion = "27.1.12297006"
        kotlinVersion = "2.1.20"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
    }
}

apply plugin: "com.facebook.react.rootproject"

allprojects {
    repositories {
        maven {
            url("$rootDir/../node_modules/detox/Detox-android")
        }
    }
}

Device Information

ios/android/simulator/emulator
WIFI
battery

Other relevant information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions