Describe the goal of the feature
Add support for B3 single-header propagation (b3: {traceid}-{spanid}-{sampled}) for both extraction and injection, alongside the existing B3 multi-header style (X-B3-*).
Proposed configuration aliases (aligned with other Datadog tracers, e.g. Java):
b3single (preferred for env-var lists; avoids space-splitting issues)
- optionally also accept
B3 single header if parsing can treat it as one token
Today PropagationStyle only has:
DATADOG
B3 (multi; also parsed from b3 / b3multi)
W3C (tracecontext)
BAGGAGE
NONE
There is no distinct B3-single style. Please add something like PropagationStyle::B3_SINGLE (name TBD) and wire it through extract/inject + DD_PROPAGATION_STYLE_* / DD_TRACE_PROPAGATION_STYLE_* parsing.
Is your feature request related to a problem?
Yes. We run Datadog tracing in Istio/Envoy, which uses dd-trace-cpp. Our mesh is configured for B3 multi so Envoy can rewrite x-b3-spanid hop-by-hop.
Many application SDKs (OpenTelemetry default B3 propagator, some dd-trace configs) still inject or prefer the single b3 header. When both single and multi headers are present, downstream extractors that prefer single can parent to a stale b3 value while Envoy has already advanced the multi headers — breaking end-to-end trace linkage across gateway → sidecar → app.
We want Istio/Envoy (via dd-trace-cpp) to be able to:
- Extract B3 single (
b3single) in addition to B3 multi, so inbound single-header context can join the mesh trace
- Optionally inject B3 single when needed for interoperability — while we would typically keep inject as multi-only in our mesh to avoid the stale-single-header problem
Without first-class b3single support, setting DD_PROPAGATION_STYLE_EXTRACT=B3,b3single,tracecontext fails with UNKNOWN_PROPAGATION_STYLE because b3single is not recognized (and note that today b3 is aliased to multi, not single).
Describe alternatives you've considered
- Application-side only: Configure every app tracer to inject B3 multi only (
b3multi) and extract both. This helps, but does not let the Envoy/Istio proxy itself accept or emit B3 single when peers still use it (e.g. Gantry/Lambda → Automat boundaries).
- Reuse
b3 for single: Not viable in dd-trace-cpp today — parse_propagation_style maps both b3 and b3multi to PropagationStyle::B3 (multi). Changing that would be a breaking change.
- W3C Trace Context only: Useful long-term, but many existing services still speak B3; we need B3 single + multi interoperability during migration.
Additional context
Current parsing (src/datadog/propagation_style.cpp):
} else if (token == "b3" || token == "b3multi") {
return PropagationStyle::B3; // multi only
}
Docs: Datadog C++ language support currently lists B3 Multi (b3 / b3multi) but not B3 Single, unlike Java (b3single / b3 single header), Node/Go/PHP/.NET (B3 single header), Python/Ruby (b3 for single).
Envoy/Istio usage: We set these via Istio meshConfig.defaultConfig.proxyMetadata:
DD_PROPAGATION_STYLE_EXTRACT: B3,b3single,tracecontext
DD_PROPAGATION_STYLE_INJECT: B3
Happy to adjust alias naming to whatever you prefer for consistency with the shared tracer config contract — we mainly need a distinct style for single-header B3 that is not conflated with multi.
Thank you!
Describe the goal of the feature
Add support for B3 single-header propagation (
b3: {traceid}-{spanid}-{sampled}) for both extraction and injection, alongside the existing B3 multi-header style (X-B3-*).Proposed configuration aliases (aligned with other Datadog tracers, e.g. Java):
b3single(preferred for env-var lists; avoids space-splitting issues)B3 single headerif parsing can treat it as one tokenToday
PropagationStyleonly has:DATADOGB3(multi; also parsed fromb3/b3multi)W3C(tracecontext)BAGGAGENONEThere is no distinct B3-single style. Please add something like
PropagationStyle::B3_SINGLE(name TBD) and wire it through extract/inject +DD_PROPAGATION_STYLE_*/DD_TRACE_PROPAGATION_STYLE_*parsing.Is your feature request related to a problem?
Yes. We run Datadog tracing in Istio/Envoy, which uses dd-trace-cpp. Our mesh is configured for B3 multi so Envoy can rewrite
x-b3-spanidhop-by-hop.Many application SDKs (OpenTelemetry default B3 propagator, some dd-trace configs) still inject or prefer the single
b3header. When both single and multi headers are present, downstream extractors that prefer single can parent to a staleb3value while Envoy has already advanced the multi headers — breaking end-to-end trace linkage across gateway → sidecar → app.We want Istio/Envoy (via dd-trace-cpp) to be able to:
b3single) in addition to B3 multi, so inbound single-header context can join the mesh traceWithout first-class
b3singlesupport, settingDD_PROPAGATION_STYLE_EXTRACT=B3,b3single,tracecontextfails withUNKNOWN_PROPAGATION_STYLEbecauseb3singleis not recognized (and note that todayb3is aliased to multi, not single).Describe alternatives you've considered
b3multi) and extract both. This helps, but does not let the Envoy/Istio proxy itself accept or emit B3 single when peers still use it (e.g. Gantry/Lambda → Automat boundaries).b3for single: Not viable in dd-trace-cpp today —parse_propagation_stylemaps bothb3andb3multitoPropagationStyle::B3(multi). Changing that would be a breaking change.Additional context
Current parsing (
src/datadog/propagation_style.cpp):Docs: Datadog C++ language support currently lists B3 Multi (
b3/b3multi) but not B3 Single, unlike Java (b3single/b3 single header), Node/Go/PHP/.NET (B3 single header), Python/Ruby (b3for single).Envoy/Istio usage: We set these via Istio
meshConfig.defaultConfig.proxyMetadata:Happy to adjust alias naming to whatever you prefer for consistency with the shared tracer config contract — we mainly need a distinct style for single-header B3 that is not conflated with multi.
Thank you!