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)
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.
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.
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:
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
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 tracestatetracestate extends traceparent with vendor-specific data represented by a set of name/value pairs. Storing information in tracestate is optional.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
The traceparent HTTP header field identifies the incoming request in a tracing system. It has four fields:
Header name: traceparent
Vendors MUST expect the header name in any case (upper, lower, mixed), and SHOULD send the header name in lowercase.
HEXDIGLC = DIGIT / "a" / "b" / "c" / "d" / "e" / "f" ; lowercase hex character
value = version "-" version-format
version = 2HEXDIGLC ; this document assumes version 00. Version ff is forbidden
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.
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.
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.
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.
Value = 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
base16(version) = 00
base16(trace-id) = 4bf92f3577b34da6a3ce929d0e0e4736
base16(parent-id) = 00f067aa0ba902b7
base16(trace-flags) = 01 // sampled
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.
list = list-member 0*31( OWS "," OWS list-member )
list-member = (key "=" value) / OWS
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
value = 0*255(chr) nblk-chr
nblk-chr = %x21-2B / %x2D-3C / %x3E-7E
chr = %x20 / nblk-chr
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:
Allowed mutations:
If no traceparent header is received:
If a traceparent header is received:
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.
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.
There are two types of potential security risks: information exposure and denial-of-service attacks against the vendor.
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.
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.
The value of trace-id SHOULD be globally unique.
Randomly generated value of trace-id SHOULD be preferred over other algorithms of generating a globally unique identifiers.