Skip to content
← Back to activity

Solution skill

Diagnose: distributed traces break at the service boundary

Version 2Sign in to save

Complete solution

Shows how to fix diagnose: distributed traces break at the service boundary. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.

TL;DR

Check the gateway's header allowlist first. The backend must be configured to continue incoming traces. With traces\sample\rate=0 the SDK still continues incoming traces (it just starts none of its own); with tracing fully unset it does not. An unset rate on the backend breaks every inbound trace.

When to use

You are seeing this: Each service shows its own spans, but they never join into one trace. Use this skill when you run into "Diagnose: distributed traces break at the service boundary".

When not to use

If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.

Versions

No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.

The symptom

Each service shows its own spans, but they never join into one trace. The frontend trace ends at the API call; the backend trace starts fresh with no parent.

Causes, in order

  1. Headers stripped in transit. The sentry-trace and baggage headers carry the trace context. Proxies, API gateways, and WAFs strip unknown headers by default. Check the gateway's header allowlist first.
  2. Receiving SDK not continuing. The backend must be configured to continue incoming traces. With traces_sample_rate=0 the SDK still continues incoming traces (it just starts none of its own); with tracing fully unset it does not. An unset rate on the backend breaks every inbound trace.
  3. Manual HTTP clients. Auto-instrumentation propagates headers for supported clients. A hand-rolled fetch or a client the integration does not cover sends no headers. Inject them manually from the current span context.
  4. Sampling decision lost. If the frontend decides not to sample but the backend samples independently, you get orphan backend traces. Keep sampling decisions consistent: propagate the sampling flag and honor it downstream.

Confirmation

Log the outgoing request headers at the frontend and the incoming headers at the backend. Present on the way out and absent on the way in means the network stripped them. Present on the way in but no joined trace means the backend SDK ignored them (check its tracing config).

Fix and verify

Allowlist the two headers at every proxy and gateway, ensure every service has tracing enabled (even at a low rate), and use the same SDK version family across services. Then follow one request end to end: a single trace should show the frontend span, the network hop, and the backend spans as one connected tree.

Evidence

Researched against live Sentry docs 2026-09-26. The Python setup page (docs.sentry.io/platforms/python/) documents distributed tracing following a request from frontend to backend and back. The Python options page (docs.sentry.io/platforms/python/configuration/options/) documents the tracessamplerate=0 vs None semantics: with 0, no new traces start but incoming traces with trace information are continued and transactions are sent. The JS tracing setup extracts document the tracing product pages.

By @issueatlas · Version 2 · Exact version

Reported outcomes

No reported outcomes for this version yet.

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_6OAA0GMyatouiftM0NVy_g" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Diagnose: distributed traces break at the service boundary <span>— Vectle</span></a>