# Trace Context

W3C Recommendation 23 November 2021

This version: https://www.w3.org/TR/2021/REC-trace-context-1-20211123/
Latest published version: https://www.w3.org/TR/trace-context-1/
Latest editor's draft: https://w3c.github.io/trace-context/

Editors:
Sergey Kanzhelev (Microsoft)
Morgan McLean (Google)
Alois Reitbauer (Dynatrace)
Bogdan Drutu (Google)
Nik Molnar (Microsoft)
Yuri Shkuro (Invited Expert)

## Abstract

This specification defines standard HTTP headers and a value format to propagate context information that enables distributed tracing scenarios. The specification standardizes how context information is sent and modified between services. Context information uniquely identifies individual requests in a distributed system and also defines a means to add and propagate provider-specific context information.

## Table of Contents

1. Abstract
2. Status of This Document
3. 1. Conformance
4. 2. Overview
   1. 2.1 Problem Statement
   2. 2.2 Solution
   3. 2.3 Design Overview
5. 3. Trace Context HTTP Headers Format
   1. 3.1 Relationship Between the Headers
   2. 3.2 Traceparent Header
   3. 3.3 Tracestate Header
   4. 3.4 Mutating the traceparent Field
   5. 3.5 Mutating the tracestate Field
6. 4. Processing Model
7. 5. Other Communication Protocols
8. 6. Privacy Considerations
9. 7. Security Considerations
10. 8. Considerations for trace-id field generation
11. A. Acknowledgments
12. B. Glossary
13. C. References

## 1. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, MUST NOT, SHOULD, and SHOULD NOT in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

## 2. Overview

### 2.1 Problem Statement

Distributed tracing is a methodology implemented by tracing tools to follow, analyze and debug a transaction across multiple software components. Typically, a distributed trace traverses more than one component which requires it to be uniquely identifiable across all participating systems. Trace context propagation passes along this unique identification. Today, trace context propagation is implemented individually by each tracing vendor. In multi-vendor environments, this causes interoperability problems, like:

- Traces that are collected by different tracing vendors cannot be correlated as there is no shared unique identifier.
- Traces that cross boundaries between different tracing vendors can not be propagated as there is no uniformly agreed set of identification that is forwarded.
- Vendor specific metadata might be dropped by intermediaries.
- Cloud platform vendors, intermediaries and service providers, cannot guarantee to support trace context propagation as there is no standard to follow.

### 2.2 Solution

The trace context specification defines a universally agreed-upon format for the exchange of trace context propagation data - referred to as trace context. Trace context solves the problems described above by

- providing an unique identifier for individual traces and requests, allowing trace data of multiple providers to be linked together.
- providing an agreed-upon mechanism to forward vendor-specific trace data and avoid broken traces when multiple tracing tools participate in a single transaction.
- providing an industry standard that intermediaries, platforms, and hardware providers can support.

### 2.3 Design Overview

Trace context is split into two individual propagation fields supporting interoperability and vendor-specific extensibility:

- `traceparent` describes the position of the incoming request in its trace graph in a portable, fixed-length format. Its design focuses on fast parsing. Every tracing tool MUST properly set traceparent even when it only relies on vendor-specific information in tracestate
- `tracestate` extends traceparent with vendor-specific data represented by a set of name/value pairs. Storing information in tracestate is optional.

## 3. Trace Context HTTP Headers Format

### 3.1 Relationship Between the Headers

The traceparent header represents the incoming request in a tracing system in a common format, understood by all vendors. Here's an example of a traceparent header.

    traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

The tracestate header includes the parent in a potentially vendor-specific format:

    tracestate: congo=t61rcWkgMzE

### 3.2 Traceparent Header

The traceparent HTTP header field identifies the incoming request in a tracing system. It has four fields:

- version
- trace-id
- parent-id
- trace-flags

#### 3.2.1 Header Name

Header name: traceparent

Vendors MUST expect the header name in any case (upper, lower, mixed), and SHOULD send the header name in lowercase.

#### 3.2.2 traceparent Header Field Values

    HEXDIGLC = DIGIT / "a" / "b" / "c" / "d" / "e" / "f" ; lowercase hex character
    value    = version "-" version-format

##### 3.2.2.1 version

    version = 2HEXDIGLC   ; this document assumes version 00. Version ff is forbidden

##### 3.2.2.2 version-format

    version-format = trace-id "-" parent-id "-" trace-flags
    trace-id       = 32HEXDIGLC  ; 16 bytes array identifier. All zeroes forbidden
    parent-id      = 16HEXDIGLC  ; 8 bytes array identifier. All zeroes forbidden
    trace-flags    = 2HEXDIGLC   ; 8 bit flags. Currently, only one bit is used.

##### 3.2.2.3 trace-id

This is the ID of the whole trace forest and is used to uniquely identify a distributed trace through a system. It is represented as a 16-byte array, for example, 4bf92f3577b34da6a3ce929d0e0e4736. All bytes as zero (00000000000000000000000000000000) is considered an invalid value.

##### 3.2.2.4 parent-id

This is the ID of this request as known by the caller (in some tracing systems, this is known as the span-id, where a span is the execution of a client request). It is represented as an 8-byte array, for example, 00f067aa0ba902b7. All bytes as zero (0000000000000000) is considered an invalid value.

##### 3.2.2.5 trace-flags

An 8-bit field that controls tracing flags such as sampling, trace level, etc. These flags are recommendations given by the caller rather than strict rules to follow.

#### 3.2.3 Examples of HTTP traceparent Headers

    Value = 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
    base16(version) = 00
    base16(trace-id) = 4bf92f3577b34da6a3ce929d0e0e4736
    base16(parent-id) = 00f067aa0ba902b7
    base16(trace-flags) = 01  // sampled

### 3.3 Tracestate Header

Header name: tracestate

The main purpose of the tracestate HTTP header is to provide additional vendor-specific trace identification information across different distributed tracing systems and is a companion header for the traceparent field.

#### 3.3.1.2 list

    list        = list-member 0*31( OWS "," OWS list-member )
    list-member = (key "=" value) / OWS

#### 3.3.1.3.1 Key

    key            = simple-key / multi-tenant-key
    simple-key     = lcalpha 0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )
    multi-tenant-key = tenant-id "@" system-id
    tenant-id      = ( lcalpha / DIGIT ) 0*240( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )
    system-id      = lcalpha 0*13( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )
    lcalpha        = %x61-7A ; a-z

#### 3.3.1.3.2 Value

    value    = 0*255(chr) nblk-chr
    nblk-chr = %x21-2B / %x2D-3C / %x3E-7E
    chr      = %x20 / nblk-chr

### 3.4 Mutating the traceparent Field

A vendor receiving a traceparent request header MUST send it to outgoing requests. It MAY mutate the value of this header before passing it to outgoing requests.

Allowed mutations:

- Update parent-id: The value of the parent-id field can be set to the new value representing the ID of the current operation.
- Update sampled: The value of the sampled field reflects the caller's recording behavior.
- Restart trace: All properties (trace-id, parent-id, trace-flags) are regenerated.
- Downgrade the version: Downgrade the version of the header.

### 3.5 Mutating the tracestate Field

Allowed mutations:

- Add a new key/value pair. The new key/value pair SHOULD be added to the beginning of the list.
- Update an existing value. Modified keys SHOULD be moved to the beginning (left) of the list.
- Delete a key/value pair. Any key/value pair MAY be deleted.

## 4. Processing Model

### 4.2 No traceparent Received

If no traceparent header is received:

1. The vendor checks an incoming request for a traceparent and a tracestate header.
2. Because the traceparent header is not received, the vendor creates a new trace-id and parent-id that represents the current request.
3. If a tracestate header is received without an accompanying traceparent header, it is invalid and MUST be discarded.
4. The vendor SHOULD create a new tracestate header and add a new key/value pair.
5. The vendor sets the traceparent and tracestate header for the outgoing request.

### 4.3 A traceparent is Received

If a traceparent header is received:

1. The vendor checks an incoming request for a traceparent and a tracestate header.
2. Because the traceparent header is present, the vendor tries to parse the version of the traceparent header.
3. The vendor MAY validate the tracestate header.
4. For each outgoing request the vendor performs the following steps: update parent-id, optionally update sampled flag, optionally modify tracestate.

## 5. Other Communication Protocols

While trace context is defined for HTTP, the authors acknowledge it is also relevant for other communication protocols. Extensions of this specification define the format of trace context serialization and deserialization for other protocols.

## 6. Privacy Considerations

Tracing vendors MUST NOT use traceparent and tracestate fields for any personally identifiable or otherwise sensitive information. The only purpose of these fields is to enable trace correlation.

## 7. Security Considerations

There are two types of potential security risks: information exposure and denial-of-service attacks against the vendor.

### 7.1 Information Exposure

Information in the traceparent and tracestate headers may carry information that can be considered sensitive. Application owners should either ensure that no proprietary or confidential information is stored in tracestate, or they should ensure that tracestate is not present in requests to external systems.

### 7.2 Denial of Service

When distributed tracing is enabled on a service with a public API and naively continues any trace with the sampled flag set, a malicious attacker could overwhelm an application with tracing overhead, forge trace-id collisions that make monitoring data unusable, or run up your tracing bill with your SaaS tracing vendor.

## 8. Considerations for trace-id field generation

### 8.1 Uniqueness of trace-id

The value of trace-id SHOULD be globally unique.

### 8.2 Randomness of trace-id

Randomly generated value of trace-id SHOULD be preferred over other algorithms of generating a globally unique identifiers.

## B. Glossary

Distributed trace
  A distributed trace is a set of events, triggered as a result of a single logical operation, consolidated across various components of an application. A distributed trace contains events that cross process, network and security boundaries.

## C. References

### C.1 Normative references

- [RFC2119] Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. https://www.rfc-editor.org/rfc/rfc2119
- [RFC5234] Augmented BNF for Syntax Specifications: ABNF. D. Crocker, Ed.; P. Overell. IETF. January 2008. https://www.rfc-editor.org/rfc/rfc5234
- [RFC7230] Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. R. Fielding, Ed.; J. Reschke, Ed.. IETF. June 2014. https://httpwg.org/specs/rfc7230.html
- [RFC8174] Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. https://www.rfc-editor.org/rfc/rfc8174