# Traceparent Header: W3C Trace Context Format

> The traceparent header carries trace id, parent span id and flags across services. Exact format, tracestate limits, OpenTelemetry, and privacy rules.

Source: https://howhttpworks.com/headers/traceparent
Last reviewed: 2026-10-04

> **TL;DR:** `traceparent` is the W3C Trace Context header that identifies a request across services: `00-<32-hex trace id>-<16-hex parent span id>-<2-hex flags>`. Every hop keeps the trace id, replaces the parent id with its own span id, and passes the header on.

## Format

```http
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
```

```text
version - trace-id (16 bytes) - parent-id (8 bytes) - trace-flags
00      - 4bf92f3577b34da6a3ce929d0e0e4736 - 00f067aa0ba902b7 - 01
```

- `version`: 2 hex characters, currently `00`. `ff` is forbidden.
- `trace-id`: 32 lowercase hex characters. All zeros is invalid.
- `parent-id`: 16 lowercase hex characters, the id of the caller's span. All zeros is invalid.
- `trace-flags`: 2 hex characters. Only the lowest bit, `sampled`, is defined.

The header name is case-insensitive on the wire, and the value is lowercase. A receiver that fails to parse it should ignore it and start a new trace.

## How a trace moves

Service A starts a trace with trace id `4bf9...`, creates span `00f0...`, and calls B with `traceparent: 00-4bf9...-00f0...-01`. B creates its own span, say `a1b2...`, and calls C with `00-4bf9...-a1b2...-01`. Trace id stays constant; parent id changes at every hop; that is how a backend rebuilds the tree.

## tracestate

```http
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: vendorA=opaque123,vendorB=t61rcWkgMzE
```

`tracestate` is a comma-separated list of vendor key=value pairs, at most 32 members, each value up to 256 printable ASCII characters. The spec says vendors should propagate at least 512 characters of the combined header. Pass it through unchanged unless you are the vendor that owns an entry; a vendor updates its own member and moves it to the front.

## Sampled flag

`01` means the caller may have recorded data for this trace. The spec treats it as advice: a callee may sample differently because of load or bugs in the caller. Head-based sampling decides at the root and everyone honors the flag; tail-based sampling ignores it and decides after the trace completes in a collector.

## OpenTelemetry

W3C Trace Context is the default propagator in OpenTelemetry SDKs, so auto-instrumented HTTP clients inject the header and servers extract it. Manual propagation in Node:

```javascript
import { context, propagation } from '@opentelemetry/api'

const headers = {}
propagation.inject(context.active(), headers)
// headers.traceparent is now set for the active span
await fetch('http://billing.internal/charge', { headers })
```

Log the trace id in every log line so logs and traces join. If you also set [X-Request-ID](https://howhttpworks.com/headers/x-request-id), keep both: the request id is the short handle for humans, the trace id is the key for your tracing backend.

## Security and privacy

- Trace ids must come from a random source that does not use anything user-identifiable (the spec says generation must not rely on such information). Do not derive them from session ids, IPs or account numbers.
- A public endpoint that honors incoming `traceparent` lets any caller force `sampled=01` and drive up tracing cost, or choose trace ids to collide with others. Many teams restart the trace at the public edge and link to the incoming id as an attribute instead.
- Do not put secrets or personal data in `tracestate` values; they travel to every downstream service, and across vendors.
- Browsers do not send `traceparent` on their own. If you add it from JavaScript to cross-origin requests, it is not CORS-safelisted and triggers a preflight, so the API must list it in `Access-Control-Allow-Headers`.

## Debug

```bash
curl -si https://api.example.com/health \
  -H 'traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01'
```

Search your tracing backend for `4bf92f3577b34da6a3ce929d0e0e4736`. If it is missing, check that a gateway is not stripping the header and that the service's propagator is configured for `tracecontext`.

## Related

- [X-Request-ID](https://howhttpworks.com/headers/x-request-id), [Server-Timing](https://howhttpworks.com/headers/server-timing), [Via](https://howhttpworks.com/headers/via)
