Traceparent Debugging: Connect Distributed Request Spans

Trace missing distributed spans by checking traceparent propagation, proxy boundaries and sampling decisions without treating trace IDs as authentication.

In this article

A distributed trace breaks when a request's context is lost or incorrectly propagated between services. Start by checking the incoming and outgoing trace context at each boundary, then investigate instrumentation and sampling. A shared request ID in logs is useful, but it is not automatically a complete distributed trace.

This guide focuses on HTTP propagation. Queue processing, background work and other transports need their own documented propagation mechanism. Do not assume that context follows a job just because it began inside a traced request.

Understand the context you are following

The W3C traceparent header carries trace identity and parent-span information in a defined format. Each service creates its own span while retaining the trace relationship. The outgoing parent information should represent the appropriate current span, not a copied arbitrary request identifier.

The W3C Trace Context specification defines the wire format. Use a maintained tracing implementation to parse and generate it. Handwritten string concatenation is easy to get wrong when invalid input, flags and version handling are involved.

Treat incoming context as untrusted metadata. It does not authenticate the caller or prove that a trace originated inside your organization. Keep authorization independent of trace IDs and sampling flags.

Map one request through the system

Choose a harmless staging request with a known path: browser to gateway, gateway to application, application to another service. List each boundary and which component injects or extracts context there.

Record sanitized evidence of the trace ID and span relationship. Avoid exporting full request headers if they include credentials or personal information. Use JSON Viewer to inspect a synthetic span summary:

json
{"service":"catalog","trace_id":"redacted",
 "span_id":"span-b","parent_span_id":"span-a",
 "operation":"lookup","exported":true}

The placeholder strings are explanatory and are not valid wire identifiers. Your implementation should validate actual identifiers using the supported tracing library.

Find the first boundary that loses context

Compare the context received by each service with the context sent onward. If the gateway receives it but the application does not, inspect gateway forwarding and request reconstruction. If the application receives it but an outbound call loses it, inspect client instrumentation.

A proxy allowlist can strip unfamiliar headers. A custom HTTP wrapper can also replace headers after instrumentation injects them. Review the actual request path rather than only the tracing configuration file.

For browser-originated calls, cross-origin policy may affect custom headers. Test the real browser request in developer tools. The HTTP Header Checker is useful for public response inspection, but it cannot prove that a private client's outgoing trace context survived every internal hop.

Check asynchronous work

Context can be lost when work moves to another thread, task or background callback without the runtime's context mechanism. The symptom may be spans with no expected parent even though all requests succeeded.

Use the tracing SDK's supported context management instead of global variables. A global current trace ID can accidentally mix concurrent requests. This is especially dangerous because the resulting traces may look connected while actually combining unrelated work.

The OpenTelemetry propagation guide explains how propagators connect execution boundaries. Confirm that every participating service uses compatible propagation settings and that asynchronous frameworks are instrumented as intended.

Separate missing context from missing exports

A service may create the right span but fail to export it. Check exporter errors, collector reachability, batching and queue limits. The request's success does not establish that telemetry delivery succeeded.

Sampling can also remove spans or whole traces from the backend. Record the sampling policy and inspect whether services make compatible decisions. Do not change every service to unlimited sampling merely to investigate a single request; use a bounded diagnostic configuration where supported.

Compare local span creation with backend ingestion. If a span exists locally but not in the tracing backend, the problem is downstream of instrumentation. If it never exists locally, focus on context and span creation first.

Keep baggage deliberate

Propagation can include additional metadata beyond trace identity. Do not put secrets, complete user profiles or unnecessary personal data into baggage. Such values may travel to more services than the originating team expects.

Define an allowlist and size limits appropriate to the application. Inspect external boundaries separately: a third-party API usually does not need your internal business metadata. Tracing should make operations easier to understand without becoming an uncontrolled data-distribution channel.

Prove the repaired relationship

Repeat the original staging request and confirm a continuous trace with the expected service spans and parent relationships. Verify concurrent requests stay separate. Include an invalid incoming header case to confirm the parser handles it safely.

Record the boundary repaired and the evidence that changed. A screenshot of a trace is useful, but a repeatable integration test protects against the next proxy or HTTP-client change.

Follow the request, then the exporter

Find the first lost context boundary before tuning telemetry storage. Keep identity, sampling and export failures distinct. For controlling telemetry growth once propagation works, see Metric Cardinality.

Advertisement
Traceparent Debugging: Connect Distributed Request Spans | Duck Cloud