OpenTelemetry Context Propagation

VerifiedSafe

Propagate trace context across service boundaries using W3C TraceContext headers and baggage.

Sby Skills Guide Bot
DevOpsIntermediate
7/22/2026
Claude CodeCursorWindsurfCopilotCodex
#opentelemetry#distributed-tracing#context-propagation#observability#w3c-tracecontext

Recommended for

Automated summary

Explains how to propagate OpenTelemetry trace context across service boundaries using W3C TraceContext, tracestate and baggage headers, with TypeScript examples for SDK setup, message queues and baggage usage.

Strengths

  • Covers concrete composite propagator setup (W3CTraceContext + W3CBaggage) in the Node SDK
  • Provides a complete manual inject/extract example for message queues where auto-instrumentation falls short
  • Documents the exact shape of traceparent, tracestate and baggage headers
  • Includes a practical baggage pattern for carrying tenant.id without changing APIs

Limitations

  • Code samples are TypeScript/Node.js only; no Python, Go or Java variants
  • The source document is truncated, so the B3/Zipkin compatibility section is incomplete
  • Assumes prior familiarity with distributed tracing concepts such as spans and contexts
When to use it

Use it when linking traces across microservices or debugging why context is lost between a producer and a consumer.

When not to use it

Skip it if the project does not use OpenTelemetry, or if you only need to instrument a single service without cross-service propagation.

Security analysis

Safe
Quality score88/100

This is a documentation-only skill about OpenTelemetry context propagation. It declares no tools, contains no executable commands, and does not instruct destructive, exfiltrating, obfuscated, or safety-disabling behavior.

No concerns found

How this analysis is made

Examples

Broken traces across a queue
My traces stop at my Node API and the RabbitMQ consumer starts a new trace. Show me how to inject the traceparent header when publishing and extract it in the consumer with OpenTelemetry.
Tenant ID via baggage
I need to pass a tenant.id from my gateway to all downstream services without adding it to every API payload. Can you implement this with OpenTelemetry baggage?
Mixed propagation formats
Some of my services use Zipkin B3 and the newer ones use W3C TraceContext. How do I configure a composite propagator in the OpenTelemetry Node SDK so both work?

OpenTelemetry Context Propagation

Propagate trace context across service boundaries using W3C TraceContext headers and baggage

When to Use

  • Linking traces across microservices into a single distributed trace
  • Passing metadata (tenant ID, feature flags) across service boundaries without modifying APIs
  • Integrating services using different languages/frameworks into one trace view
  • Debugging why context is lost between services (broken traces)

Instructions

  1. Register propagators in the SDK setup. W3C TraceContext is the default and recommended standard.
  2. HTTP auto-instrumentation handles propagation automatically for most frameworks. Verify it works before adding manual propagation.
  3. For non-HTTP transports (queues, gRPC metadata, custom protocols), inject context into carrier objects manually.
  4. Use Baggage to pass key-value pairs across service boundaries (tenant ID, request priority).
  5. Ensure all services in the chain use the same propagation format (W3C, B3, or both via composite propagator).
// SDK setup — configure propagators
import { W3CTraceContextPropagator } from '@opentelemetry/core';
import { W3CBaggagePropagator } from '@opentelemetry/core';
import { CompositePropagator } from '@opentelemetry/core';

const sdk = new NodeSDK({
  textMapPropagator: new CompositePropagator({
    propagators: [
      new W3CTraceContextPropagator(), // traceparent + tracestate headers
      new W3CBaggagePropagator(), // baggage header
    ],
  }),
  // ... rest of config
});
// Manual propagation for message queues
import { context, propagation, trace } from '@opentelemetry/api';

// Producer — inject context into message headers
function publishMessage(queue: string, payload: object): void {
  const headers: Record<string, string> = {};
  propagation.inject(context.active(), headers);

  messageQueue.publish(queue, {
    body: payload,
    headers, // Contains traceparent, tracestate, baggage
  });
}

// Consumer — extract context from message headers
async function consumeMessage(message: QueueMessage): Promise<void> {
  const parentContext = propagation.extract(context.active(), message.headers);

  const tracer = trace.getTracer('consumer');
  await context.with(parentContext, async () => {
    await tracer.startActiveSpan(
      'process.message',
      {
        kind: SpanKind.CONSUMER,
        attributes: { 'messaging.system': 'rabbitmq', 'messaging.destination': message.queue },
      },
      async (span) => {
        try {
          await processMessage(message.body);
        } finally {
          span.end();
        }
      }
    );
  });
}
// Baggage — pass metadata across services
import { propagation, context, BaggageEntry } from '@opentelemetry/api';

// Set baggage in the upstream service
function setTenantContext(tenantId: string) {
  const baggage = propagation.createBaggage({
    'tenant.id': { value: tenantId },
    'request.priority': { value: 'high' },
  });
  return propagation.setBaggage(context.active(), baggage);
}

// Read baggage in the downstream service
function getTenantId(): string | undefined {
  const baggage = propagation.getBaggage(context.active());
  return baggage?.getEntry('tenant.id')?.value;
}

Details

W3C TraceContext headers:

  • traceparent: 00-<traceId>-<spanId>-<flags> — the core propagation header
  • tracestate: vendor1=value1,vendor2=value2 — vendor-specific trace information
  • baggage: tenant.id=abc,priority=high — application-level key-value pairs

Auto-propagation: The HTTP instrumentation automatically injects traceparent on outgoing requests and extracts it on incoming requests. You typically do NOT need manual propagation for HTTP.

When you need manual propagation:

  • Message queues (RabbitMQ, Kafka, SQS)
  • gRPC metadata
  • WebSocket messages
  • Custom RPC protocols
  • Cron jobs that should link to the triggering request

B3 compatibility: If some services use Zipkin B3 headers, add the B3 propagator:

import { B3Propagator } from '@opentelemetry/propagator-b3';

new CompositePropagator({
  propagators: [
    new W3CTraceContextPropagator(),
    new B3Propagator(), // Also understands X-B3-TraceId headers
  ],
});

Debugging broken traces: If traces are disconnected across services:

  1. Check that both services use the same propagation format
  2. Verify the HTTP client is instrumented (auto-instrumentation must be loaded)
  3. Check for reverse proxies stripping traceparent headers
  4. For async operations, verify context is passed through context.with()

Source

https://opentelemetry.io/docs/concepts/context-propagation/

Process

  1. Read the instructions and examples in this document.
  2. Apply the patterns to your implementation, adapting to your specific context.
  3. Verify your implementation against the details and edge cases listed above.

Harness Integration

  • Type: knowledge — this skill is a reference document, not a procedural workflow.
  • No tools or state — consumed as context by other skills and agents.

Success Criteria

  • The patterns described in this document are applied correctly in the implementation.
  • Edge cases and anti-patterns listed in this document are avoided.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/opentelemetry-context-propagation-mrwakcvk/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/opentelemetry-context-propagation-mrwakcvk' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/opentelemetry-context-propagation-mrwakcvk/download' --output '.skill-downloads/opentelemetry-context-propagation-mrwakcvk/SKILL.md.part' && mv '.skill-downloads/opentelemetry-context-propagation-mrwakcvk/SKILL.md.part' '.skill-downloads/opentelemetry-context-propagation-mrwakcvk/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

This file does not provide a usable name/description header for this native procedure. It remains available to download and inspect; use the manual method below.

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/opentelemetry-context-propagation-mrwakcvk/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills