This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
devopscritical PriorityID: opentelemetry-w3c-tracecontext-async-broker-fabric-standard

OpenTelemetry W3C TraceContext Propagation for Asynchronous Message Fabrics

Eliminates distributed trace fragmentation across asynchronous message brokers such as Apache Kafka and NATS JetStream by mandating deterministic W3C TraceContext propagation. Enforces OpenTelemetry messaging semantic conventions, zero-allocation header manipulation, explicit carrier extraction/injection, and SpanKind boundary enforcement.

Prohibited Anti-Pattern: Silent Distributed Trace Decoupling via Header Dropping and Context Disconnection

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenTelemetry W3C TraceContext Propagation for Asynchronous Message Fabrics - Eliminates distributed trace fragmentation across asynchronous message brokers such as Apache Kafka and NATS JetStream by mandating deterministic W3C TraceContext propagation. Enforces OpenTelemetry messaging semantic conventions, zero-allocation header manipulation, explicit carrier extraction/injection, and SpanKind boundary enforcement.
globs: src/events/**/*.{ts,tsx,js,jsx}, src/messaging/**/*.{ts,tsx,js,jsx}, src/producers/**/*.{ts,tsx,js,jsx}, src/consumers/**/*.{ts,tsx,js,jsx}, src/infrastructure/broker/**/*.{ts,tsx,js,jsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/opentelemetry-w3c-tracecontext-async-broker-fabric-standard"
---

# OpenTelemetry W3C TraceContext Propagation for Asynchronous Message Fabrics

> **Severity**: CRITICAL | **Category**: devops
> **Anti-Pattern Warning**: Silent Distributed Trace Decoupling via Header Dropping and Context Disconnection

## System Constraints
You are a Principal Software Architect enforcing the OpenTelemetry W3C TraceContext Async Broker Fabric Standard. You must mandate zero trace-context drops, ensure strict OpenTelemetry Messaging Semantic Conventions, enforce W3C traceparent/tracestate header propagation via zero-allocation or zero-mutation carriers, and prevent consumer context isolation during batch and fan-out stream processing across Kafka and NATS JetStream.

## Strict Guidelines
- Engineers MUST ALWAYS inject the active OpenTelemetry context into outgoing broker headers using propagation.inject() with a specialized TextMapSetter before producing messages.
- Engineers MUST ALWAYS extract parent context from incoming message headers using propagation.extract() with a specialized TextMapGetter before invoking consumer business logic.
- Engineers MUST set SpanKind.PRODUCER for dispatch spans and SpanKind.CONSUMER (or SpanKind.INTERNAL with SpanLinks for batched records) in accordance with OpenTelemetry Messaging Semantic Conventions.
- Engineers MUST NOT rely on implicit global context in asynchronous broker handlers, as async event loops and batch processing decouple active execution scopes.
- Services MUST capture messaging attributes: messaging.system (kafka, nats), messaging.destination.name, messaging.operation (publish, receive, process), and messaging.message.id.
- Batch consumers MUST create individual consumer spans linked via SpanLink to each extracted message context to prevent single-parent hierarchy skew.
- Components NEVER drop or mutate W3C traceparent and tracestate headers during message serialization, deserialization, or topic re-routing.

## Bad vs Good Implementations
### Kafka Producer & Consumer W3C TraceContext Propagation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The producer dispatches messages without injecting the active W3C traceparent/tracestate into Kafka record headers. The consumer then initializes a fresh trace with startActiveSpan without extracting the context from message.headers. This causes 100% trace drop across the asynchronous boundary.
```typescript
import { Kafka, Producer, EachMessagePayload } from 'kafkajs';
import { trace } from '@opentelemetry/api';

const tracer = trace.getTracer('order-service');

export async function publishOrder(producer: Producer, order: { id: string }) {
  // Anti-pattern: Tracing is separated from broker payload headers.
  // Context is not injected, causing downstream consumer trace fragmentation.
  return tracer.startActiveSpan('publishOrder', async (span) => {
    await producer.send({
      topic: 'orders.v1',
      messages: [{ key: order.id, value: JSON.stringify(order) }]
    });
    span.end();
  });
}

export async function consumeOrder(payload: EachMessagePayload) {
  // Anti-pattern: Consumer creates a root trace completely disjoint
  // from the producer because incoming headers are completely ignored.
  return tracer.startActiveSpan('processOrder', async (span) => {
    const order = JSON.parse(payload.message.value!.toString());
    // Business logic runs in an isolated trace context
    span.end();
  });
}
```

#### Production Standard (Correct)
> **Standard**: Implements explicit W3C TraceContext propagation using typed TextMapSetter/Getter adapters. Producer attaches traceparent/tracestate into Kafka record headers with SpanKind.PRODUCER. Consumer extracts parent context via propagation.extract and binds the SpanKind.CONSUMER span to the active asynchronous execution chain.
```typescript
import { Producer, EachMessagePayload, IHeaders } from 'kafkajs';
import {
  trace,
  context,
  propagation,
  SpanKind,
  SpanStatusCode,
  TextMapSetter,
  TextMapGetter,
  ROOT_CONTEXT
} from '@opentelemetry/api';
import {
  SEMATTRS_MESSAGING_SYSTEM,
  SEMATTRS_MESSAGING_DESTINATION_NAME,
  SEMATTRS_MESSAGING_OPERATION
} from '@opentelemetry/semantic-conventions';

const tracer = trace.getTracer('order-service');

const kafkaHeaderSetter: TextMapSetter<IHeaders> = {
  set(carrier, key, value) {
    carrier[key] = Buffer.from(value, 'utf-8');
  }
};

const kafkaHeaderGetter: TextMapGetter<IHeaders> = {
  get(carrier, key) {
    const val = carrier?.[key];
    if (!val) return undefined;
    return Buffer.isBuffer(val) ? val.toString('utf-8') : String(val);
  },
  keys(carrier) {
    return carrier ? Object.keys(carrier) : [];
  }
};

export async function publishOrder(producer: Producer, order: { id: string }) {
  const span = tracer.startSpan('orders.v1 publish', {
    kind: SpanKind.PRODUCER,
    attributes: {
      [SEMATTRS_MESSAGING_SYSTEM]: 'kafka',
      [SEMATTRS_MESSAGING_DESTINATION_NAME]: 'orders.v1',
      [SEMATTRS_MESSAGING_OPERATION]: 'publish'
    }
  });

  const outgoingHeaders: IHeaders = {};
  const tracingContext = trace.setSpan(context.active(), span);
  propagation.inject(tracingContext, outgoingHeaders, kafkaHeaderSetter);

  try {
    await producer.send({
      topic: 'orders.v1',
      messages: [{
        key: order.id,
        value: JSON.stringify(order),
        headers: outgoingHeaders
      }]
    });
    span.setStatus({ code: SpanStatusCode.OK });
  } catch (err: any) {
    span.recordException(err);
    span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
    throw err;
  } finally {
    span.end();
  }
}

export async function consumeOrder(payload: EachMessagePayload) {
  const extractedContext = propagation.extract(
    ROOT_CONTEXT,
    payload.message.headers,
    kafkaHeaderGetter
  );

  const span = tracer.startSpan(
    'orders.v1 process',
    {
      kind: SpanKind.CONSUMER,
      attributes: {
        [SEMATTRS_MESSAGING_SYSTEM]: 'kafka',
        [SEMATTRS_MESSAGING_DESTINATION_NAME]: payload.topic,
        [SEMATTRS_MESSAGING_OPERATION]: 'process'
      }
    },
    extractedContext
  );

  await context.with(trace.setSpan(extractedContext, span), async () => {
    try {
      const order = JSON.parse(payload.message.value!.toString());
      // Execute business logic with preserved distributed context
      span.setStatus({ code: SpanStatusCode.OK });
    } catch (err: any) {
      span.recordException(err);
      span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
      throw err;
    } finally {
      span.end();
    }
  });
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: OpenTelemetry W3C TraceContext Propagation for Asynchronous Message Fabrics

OpenTelemetry W3C TraceContext Propagation for Asynchronous Message Fabrics defines an industrial-grade behavioral standard for devops engineering. Eliminates distributed trace fragmentation across asynchronous message brokers such as Apache Kafka and NATS JetStream by mandating deterministic W3C TraceContext propagation. Enforces OpenTelemetry messaging semantic conventions, zero-allocation header manipulation, explicit carrier extraction/injection, and SpanKind boundary enforcement. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Silent Distributed Trace Decoupling via Header Dropping and Context Disconnection Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftSilent Distributed Trace Decoupling via Header Dropping and Context DisconnectionCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS inject the active OpenTelemetry context into outgoing broker headers using propagation.inject() with a specialized TextMapSetter before producing messages.

Engineers MUST ALWAYS inject the active OpenTelemetry context into outgoing broker headers using propagation.inject() with a specialized TextMapSetter before producing messages.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST ALWAYS extract parent context from incoming message headers using propagation.extract() with a specialized TextMapGetter before invoking consumer business logic.

Engineers MUST ALWAYS extract parent context from incoming message headers using propagation.extract() with a specialized TextMapGetter before invoking consumer business logic.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST set SpanKind.PRODUCER for dispatch spans and SpanKind.CONSUMER (or SpanKind.INTERNAL with SpanLinks for batched records) in accordance with OpenTelemetry Messaging Semantic Conventions.

Engineers MUST set SpanKind.PRODUCER for dispatch spans and SpanKind.CONSUMER (or SpanKind.INTERNAL with SpanLinks for batched records) in accordance with OpenTelemetry Messaging Semantic Conventions.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Engineers MUST NOT rely on implicit global context in asynchronous broker handlers, as async event loops and batch processing decouple active execution scopes.

Engineers MUST NOT rely on implicit global context in asynchronous broker handlers, as async event loops and batch processing decouple active execution scopes.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Services MUST capture messaging attributes

Services MUST capture messaging attributes: messaging.system (kafka, nats), messaging.destination.name, messaging.operation (publish, receive, process), and messaging.message.id.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Batch consumers MUST create individual consumer spans linked via SpanLink to each extracted message context to prevent single-parent hierarchy skew.

Batch consumers MUST create individual consumer spans linked via SpanLink to each extracted message context to prevent single-parent hierarchy skew.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
7

Components NEVER drop or mutate W3C traceparent and tracestate headers during message serialization, deserialization, or topic re-routing.

Components NEVER drop or mutate W3C traceparent and tracestate headers during message serialization, deserialization, or topic re-routing.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is OpenTelemetry W3C TraceContext Propagation for Asynchronous Message Fabrics critical for AI coding assistants?

Eliminates distributed trace fragmentation across asynchronous message brokers such as Apache Kafka and NATS JetStream by mandating deterministic W3C TraceContext propagation. Enforces OpenTelemetry messaging semantic conventions, zero-allocation header manipulation, explicit carrier extraction/injection, and SpanKind boundary enforcement. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Silent Distributed Trace Decoupling via Header Dropping and Context Disconnection) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

OpenTelemetry