Trace context headers not propagating between OpenTelemetry and Elastic APM
Use this guide to troubleshoot missing or broken distributed traces when combining OpenTelemetry instrumentation with Elastic APM agents.
Mixing OpenTelemetry and non-OpenTelemetry (Elastic APM agent) configurations is not officially supported. This guide is only intended for troubleshooting trace context propagation during gradual migrations or partial instrumentation.
The recommended path is to adopt an OpenTelemetry-native strategy using Elastic Distribution of OpenTelemetry. However, if you are in a transition period, this page helps you diagnose and mitigate trace context propagation issues (traceparent / tracestate) until you can complete the migration.
You might observe one or more of the following issues:
- Distributed traces are broken across service boundaries.
- Downstream spans start new traces instead of continuing the existing one.
- Traces appear split or uncorrelated in the UI.
- Parent–child relationships are missing when traffic crosses between:
- OpenTelemetry-instrumented services and Elastic APM agents
- New and legacy Elastic APM agents in the same call chain
- Different versions of APM agents in the same call chain
In mixed OpenTelemetry and Elastic APM environments, propagation issues typically stem from header or configuration mismatches.
OpenTelemetry uses the W3C Trace Context standard headers:
traceparenttracestate
All modern Elastic APM agents support W3C Trace Context by default.
For backward compatibility, Elastic agents also support a legacy proprietary header (elastic-apm-traceparent) and operate in dual‑propagation mode:
- Inbound: Agents first read W3C headers; if missing, they fall back to the legacy header.
- Outbound: Agents inject both W3C headers and the legacy header to support mixed environments.
Propagation issues often occur when:
- Older (pre‑W3C) Elastic agents are still in use.
- Legacy propagation is turned off prematurely.
- Trace continuation is misconfigured to restart traces.
- Two tracing SDKs run in the same process and compete for instrumentation or context.
Before going fully OTel-native, you can use the OpenTelemetry Bridge offered by Elastic agents as a transitional solution:
The bridge lets you use the OpenTelemetry API for manual instrumentation while still using an Elastic APM agent for auto‑instrumentation and exporting.
With the bridge:
- The Elastic agent implements the OpenTelemetry API.
- Spans created through the OTel API become native Elastic spans.
- Parent–child relationships are preserved across manual and auto‑instrumentation.
The bridge is available in major Elastic agents (Java, .NET, Node.js, Python). Prefer moving to Elastic Distribution of OpenTelemetry (OTel-native) when you can.
Do not run a full OpenTelemetry SDK in the same process as an Elastic APM agent.
This setup causes:
- Duplicate instrumentation and added overhead.
- Trace fragmentation (conflicting trace IDs).
- Startup conflicts (instrumentation, exporters, environment variables).
Each SDK might try to manage propagation independently, breaking distributed tracing. For an OpenTelemetry-native setup, use Elastic Distribution of OpenTelemetry instead of mixing SDKs.
The preferred resolution is to complete your migration to OpenTelemetry and use Elastic Distribution of OpenTelemetry (OTel-native). However, if you are still in a gradual migration and need traces to connect across mixed services, the following steps might help.
-
Ensure all services support W3C Trace Context
If you still have Elastic agents in the call path, verify that they support W3C Trace Context.
Agent Minimum version Java 1.14.0 .NET 1.3.0 Node.js 3.4.0 Python 5.4.0 Go 1.6.0 Ruby 3.5.0 PHP 1.0.0 RUM (JS) 5.0.0 All recent releases prefer W3C propagation by default.
-
Verify propagation and trace continuation settings
Ensure agents:
- Have W3C propagation turned on (default).
- Retain legacy propagation if older agents are still present.
- Are not misconfigured to restart traces unexpectedly.
Some agents expose a trace continuation strategy (for example, .NET):
continue(default): Continue incoming traces.restart: Always start a new trace.restart_external: Restart only for non-Elastic sources.
Unexpected trace restarts might indicate incorrect strategy settings.
-
Use the OpenTelemetry Bridge
If you're in transition and still use the OpenTelemetry API with an Elastic agent:
- Turn on the OpenTelemetry Bridge in the agent.
- Do not install a separate OpenTelemetry SDK in the same process.
This can help maintain context propagation during the migration. Plan to move to Elastic Distribution of OpenTelemetry (OTel-native) when possible.
-
Keep dual‑propagation active during migrations
In mixed environments with OpenTelemetry SDKs (W3C only) and earlier versions of Elastic agents, keep the default dual‑propagation mode turned on so that:
- New services read W3C headers.
- Legacy services read the
elastic-apm-traceparentheader.
Turning off the legacy header too early can break trace continuity.
-
Turn off legacy headers after full migration
When all services support W3C Trace Context, you might turn off emission of the legacy header to reduce header size and network overhead.
Refer to agent-specific documentation to turn off legacy header output.
- Use Elastic Distribution of OpenTelemetry for full OTel support and to avoid mixed-configuration issues.
- If you are in a gradual migration: standardize on W3C Trace Context across services and upgrade older agents early.
- Use one tracing implementation per process (Elastic agent or OpenTelemetry SDK). Avoid mixing SDKs.
- If you must mix APIs during a transition, use the OpenTelemetry Bridge temporarily and plan to move to Elastic Distribution of OpenTelemetry.
- Validate cross-service tracing in staging before partial rollouts.