'm troubleshooting a distributed-trace correlation issue and would like to confirm Cloud Run’s behavior around W3C traceparent injection.
Architecture: Client → Apigee /api-1 → Cloud Run (Java app, OTel-instrumented) → Apigee /api-2 → Cloud Run (Java app, OTel-instrumented)
-
Apigee propagates trace context using B3 only (x-b3-traceid, x-b3-spanid). It does not emit W3C traceparent.
-
Cloud Run appears to inject its own W3C traceparent on every inbound request, with a different trace ID than the x-b3-traceid already set by Apigee.
-
Result: the app receives two conflicting headers, and our OpenTelemetry SDK (OTEL_PROPAGATORS=tracecontext,b3multi,baggage) has to pick one.
This is causing observability issues as by our observability tool (Dynatrace OneAgent) gets to the request, it only grabs the Cloud Run W3C traceparent, as it doesn’t support B3 by itself, thus losing Apigee/Otel correlation.
When Cloud Run injects traceparent on inbound requests, can it be configured to derive the trace ID from an existing x-b3-traceid header (if present) instead of generating a fresh one? Goal: both headers carry identical trace/span IDs so downstream W3C-only consumers (Dynatrace OneAgent) and B3-aware consumers (2nd apigee call) see the same trace.
If that isn’t directly supported, is there a documented way to influence the trace ID Cloud Run uses when generating traceparent
If none of the above is possible, is there a Google-recommended pattern for bridging B3 → W3C at the Cloud Run boundary when the upstream gateway only speaks B3?
Cloud Run automatically overrides incoming requests with its own W3C traceparent header to enforce Cloud Trace continuity, dropping or ignoring Apigee’s x-b3-traceid. To bridge this gap, use Apigee to inject W3C headers into the outgoing request, or use an API Gateway as an intermediate translation layer.
Bridging Apigee to Cloud Run Trace ContextCloud Run derives its trace ID from external infrastructure (like an external Load Balancer) or generates a completely fresh W3C traceparent. It does not parse incoming B3 headers.
Implement one of the following patterns to ensure observability tools like Dynatrace OneAgent can correlate endpoints across both platforms:1. Inject W3C Headers in Apigee (Recommended)Because Cloud Run respects and propagates W3C headers natively, the most reliable approach is to have Apigee do the translation before it calls Cloud Run.
TraceCapture Policy: Configure your Apigee environment to support OpenTelemetry or W3C context and propagate W3C headers in your Target Endpoints.
JavaScript / AssignMessage Policy: If Apigee is strictly bound to B3 headers, attach an Assign Message Policy or JavaScript policy in the TargetEndpoint’s PreFlow to derive or convert the B3 trace ID. You can map x-b3-traceid into a properly formatted W3C traceparent string (e.g., 00-{trace-id}-{span-id}-01).
Use an API Gateway / Envoy ProxyIf modifying Apigee is not immediately feasible, interpose a Google Cloud API Gateway or an Envoy Proxy configured as a bridge between Apigee and Cloud Run
Envoy provides pluggable tracing that can ingest x-b3-traceid and bridge it to W3C format using custom connection manager extensions
Standardize on Dynatrace SDKSince Dynatrace’s OneAgent supports W3C trace context, ensuring Apigee passes W3C headers will seamlessly stitch the trace together. If headers are dropped, you can manually use the Dynatrace OneAgent SDK in the Cloud Run
application code to manually read Apigee’s B3 headers and stitch the transaction.