traceparent Decoder — W3C Trace Context
Stop counting hex digits. Free online traceparent decoder — runs in your browser, nothing uploaded. Trace ID, span ID, all 8 trace-flags bits, tracestate check, Datadog/X-Ray/B3 conversion.
- Version
00- Trace ID
4bf92f3577b34da6a3ce929d0e0e4736- Parent ID (span ID)
00f067aa0ba902b7- Trace flags
01
| Bit | Mask | Name | State |
|---|---|---|---|
| 0 | 0x01 | sampled | 1 |
| 1 | 0x02 | random-trace-id | 0 |
| 2 | 0x04 | reserved | 0 |
| 3 | 0x08 | reserved | 0 |
| 4 | 0x10 | reserved | 0 |
| 5 | 0x20 | reserved | 0 |
| 6 | 0x40 | reserved | 0 |
| 7 | 0x80 | reserved | 0 |
Read these with a bitwise AND. Comparing the whole byte to 01 misreports any trace that also carries a reserved bit.
- x-datadog-trace-id
11803532876627986230- x-datadog-tags: _dd.p.tid
4bf92f3577b34da6- x-datadog-parent-id
67667974448284343- AWS X-Ray trace ID
1-4bf92f35-77b34da6a3ce929d0e0e4736- b3 (single header)
4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1- X-B3-TraceId
4bf92f3577b34da6a3ce929d0e0e4736- X-B3-SpanId
00f067aa0ba902b7- X-B3-Sampled
1
Datadog carries the lower 64 bits of the trace ID as a decimal string and the higher 64 bits as hex in a tag. Passing the whole 128-bit value as decimal is the classic reason a trace ID from your logs finds nothing in the UI.
An X-Ray ID embeds a 32-bit timestamp; a W3C trace ID does not carry a timestamp at all. The date below is only meaningful if the identifier actually originated in X-Ray.
| # | Key | Value | Status |
|---|---|---|---|
| 1 | rojo | 00f067aa0ba902b7 | OK |
| 2 | congo | t61rcWkgMzE | OK |
traceparent Format: Field Anatomy
| Field | Hex digits | Bytes | Meaning | Invalid value |
|---|---|---|---|---|
| version | 2 | 1 | Format version. Always 00 today; ff is forbidden. | ff |
| trace-id | 32 | 16 | Identifies the whole trace end to end. | All zeros |
| parent-id | 16 | 8 | Identifies the calling span, not the request. | All zeros |
| trace-flags | 2 | 1 | An 8-bit field — read it bit by bit, never as a boolean. | — |
trace-flags Values: 00, 01, 02 and 03 Explained
| Hex | Binary | sampled | random-trace-id | Meaning |
|---|---|---|---|---|
| 00 | 00000000 | 0 | 0 | Upstream chose not to sample — look at the caller, not your service. |
| 01 | 00000001 | 1 | 0 | Recorded normally. This is what you see most of the time. |
| 02 | 00000010 | 0 | 1 | Random trace ID declared, but not sampled. |
| 03 | 00000011 | 1 | 1 | Recorded, and the trace ID is declared uniformly random. |
bit 0 — The caller recorded this trace. Clear means it deliberately chose not to.
bit 1 — Level 2: the right-most 7 bytes of the trace ID are uniformly random.
bit 2-7 — Reserved. Must be ignored, and cleared on outbound requests.
Built directly against the W3C Trace Context recommendation and the Level 2 candidate recommendation, with the parser covered by unit tests for every valid and invalid form the specification names.
What Is the traceparent Header?
traceparent is the HTTP header that carries a distributed trace from one service to the next. Before it was standardised, every tracing vendor propagated context in its own header, so a request that crossed systems lost its identity at the boundary. The W3C Trace Context specification fixed that with a single, deliberately small format: version-trace-id-parent-id-trace-flags, four hexadecimal fields joined by dashes, 55 characters in total for the current version.
Each field does one job. The version is always 00 today, and ff is forbidden outright. The trace-id is 16 bytes identifying the whole request end to end — it stays constant across every hop. The parent-id is 8 bytes identifying the immediate caller's span, so unlike the trace-id it changes at every hop. The trace-flags byte is where most confusion lives: it looks like a boolean because 01 is by far the most common value, but it is eight bits. Bit 0 is sampled. Bit 1, added in Trace Context Level 2, is random-trace-id, asserting that the right-most seven bytes of the trace ID are uniformly random so that downstream systems may sample or shard on them. The remaining six bits are reserved, which is precisely why the field must be read with a bitwise AND rather than compared for equality.
A companion header, tracestate, carries vendor-specific key-value pairs alongside it, capped at 32 members. That ceiling explains a puzzling symptom: vendor data that is present at the edge and gone several hops later, because intermediaries began dropping entries once the list grew past the limit. The header became genuinely universal once OpenTelemetry adopted it, and this page decodes all of it — fields, bits, tracestate members and the equivalent identifiers for other propagation formats — without sending anything anywhere.
# The header as it travels on the wire
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE
# Read the four fields apart
# version 00
# trace-id 4bf92f3577b34da6a3ce929d0e0e4736 (16 bytes, whole request)
# parent-id 00f067aa0ba902b7 (8 bytes, calling span)
# trace-flags 01 (bit 0 set = sampled)
# Send one yourself
$ curl -H 'traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01' \
https://example.com/api Key Features
Every field, split and copyable
Version, trace-id, parent-id and trace-flags each get their own row and their own copy button, so lifting a 32-character trace ID into a query takes one click instead of a careful drag.
trace-flags read as eight bits
The flags byte is expanded into all eight positions with their hexadecimal masks. Bit 0 is sampled, bit 1 is the Level 2 random-trace-id flag, and the reserved bits are shown rather than silently discarded.
Datadog, X-Ray and B3 conversion
The lower 64 bits as a decimal Datadog trace ID, the higher 64 bits as the tag that travels with it, the X-Ray 1-{8}-{24} form, and both the single and multi-header B3 layouts — all computed with BigInt so nothing overflows.
Diagnoses, not just verdicts
An all-zero trace ID is explained as tracing that never initialised; a cleared sampled bit is explained as a decision made upstream. Knowing which of the two you are looking at is usually the whole debugging session.
tracestate with the 32-member ceiling
Members are listed with per-member key and value validation and a running count against the specification's limit — the limit that explains why vendor data vanishes a few hops downstream.
Nothing leaves your browser
Parsing is plain string and BigInt arithmetic with no dependencies and no network calls, verified by an automated contract test on every build. Copy link uses the URL fragment, which is never transmitted.
traceparent Examples, Decoded
The specification's own example, decoded
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
version 00 · trace-id 4bf92f3577b34da6a3ce929d0e0e4736 · parent-id 00f067aa0ba902b7 · trace-flags 01 (sampled)
Four dash-separated fields, 55 characters in total for version 00. The trace-id identifies the entire request as it crosses every service; the parent-id — often called the span ID — identifies only the immediate caller, which is why it changes on every hop while the trace-id does not. The trailing 01 is a full byte, not a boolean: bit 0 is set, so the caller recorded this trace.
trace-flags 00 — the caller decided not to record
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00
Valid header · sampled bit clear
This header is perfectly valid, and that is the point. A cleared sampled bit is an instruction from upstream, not a defect in your service: whoever called you evaluated their sampler and chose not to record. Chasing missing spans in your own configuration here wastes hours. The question to ask is which service is calling you, sending a parent span, and deciding not to sample the trace.
An all-zero trace ID means tracing never started
00-00000000000000000000000000000000-00f067aa0ba902b7-01
Invalid — all-zero trace-id
The specification declares an all-zero trace-id invalid, and requires that the whole traceparent be ignored. It is worth knowing what it signals in practice: not "a trace that has no data yet", but an SDK that was never initialised, or a middleware injecting a placeholder header. The same rule applies to an all-zero parent-id.
The same trace ID in Datadog's format
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
x-datadog-trace-id 11803532876627986230 · _dd.p.tid 4bf92f3577b34da6
Datadog carries the lower 64 bits of a 128-bit trace ID as a decimal string, and the higher 64 bits as hexadecimal in a separate tag. Feed the whole 128-bit value in as decimal and you get a number that matches nothing — which is exactly why this conversion turns up again and again in tracer issue trackers. The lower half here is a3ce929d0e0e4736, and 64 bits exceeds what a JavaScript number can hold, so this page does the arithmetic with BigInt.
How to Use the traceparent Decoder
- 1
Paste the traceparent header
Drop in the raw header value — for example 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01. Decoding happens as you type; there is no button to press.
- 2
Read the four fields apart
Version, trace-id, parent-id and trace-flags are split into their own rows, each with a copy button, so you can lift just the trace ID into a query without hand-selecting 32 characters.
- 3
Check the flags bit by bit
The trace-flags byte is expanded into all eight bits with their masks, so sampled and the Level 2 random-trace-id flag are visible individually rather than hidden inside a two-character value.
- 4
Convert to your backend's format
Datadog, AWS X-Ray and both B3 forms are generated underneath, including the lower-64-bit decimal trace ID that Datadog expects and the higher-64-bit tag that travels alongside it.
- 5
Add tracestate and share the result
Paste a tracestate header to list its members with per-member validation and a count against the 32-member limit, then use Copy link to capture the exact state in a URL you can drop into a ticket.
Common traceparent Mistakes
Comparing the whole flags byte to 01
This treats an eight-bit field as an enumeration. A trace that is sampled and also carries the Level 2 random-trace-id flag has flags 03, and the equality check reports it as not sampled.
if (traceFlags === 0x01) { record(); } if (traceFlags & 0x01) { record(); } Converting all 128 bits to one decimal number
Datadog expects the lower 64 bits as decimal and the higher 64 bits as hexadecimal in a separate tag. Passing the full value as one decimal number produces an identifier that matches nothing.
x-datadog-trace-id: 100985939111033328018442752961257817910
x-datadog-trace-id: 11803532876627986230 x-datadog-tags: _dd.p.tid=4bf92f3577b34da6
Rejecting any version that is not 00
The specification asks parsers to read what they recognise from a higher version and tolerate trailing fields. Rejecting outright restarts the trace and breaks the link across the boundary.
if (version !== '00') throw new Error('bad traceparent'); if (version !== '00' && header.length >= 55) { /* parse the known prefix */ } Emitting uppercase hexadecimal
The grammar admits lowercase only. An uppercase trace ID carries the right value and is still rejected by a conforming receiver, which makes it a particularly frustrating bug to spot by eye.
traceparent: 00-4BF92F3577B34DA6A3CE929D0E0E4736-00F067AA0BA902B7-01
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
What You Can Do with the traceparent Decoder
- Work out why a trace has no spans
- Paste the incoming header and read the sampled bit. If it is clear, the trace was never going to be recorded and the answer lies with the caller, not with your instrumentation — a distinction that saves a great deal of time spent auditing your own sampler configuration.
- Find a trace that your backend cannot
- When a trace ID copied from application logs returns nothing in Datadog, the format is usually the culprit. Convert it here to see the lower-64-bit decimal identifier the API expects, along with the higher-64-bit tag that has to accompany it.
- Verify headers your gateway injects
- Proxies and service meshes generate trace context on the way in. Paste what actually arrived to confirm the length, lowercase hexadecimal and non-zero identifiers before assuming the fault is downstream.
- Reproduce a production trace by hand
- Take a header from a real request and replay it against a staging endpoint to follow the same trace through. Build the request with the curl command builder and paste the header straight into it.
- Explain trace context to a team
- The field anatomy and trace-flags tables on this page are static reference material you can point at, and the preset chips demonstrate each failure mode without anyone having to break a service to produce one.
How the W3C Trace Context Validator Works
- The four-field grammar
- version "-" trace-id "-" parent-id "-" trace-flags, all lowercase hexadecimal. Version is 2 digits, trace-id 32, parent-id 16 and trace-flags 2 — 52 hex digits plus 3 dashes, 55 characters exactly for version 00. Uppercase hexadecimal makes the header invalid even though the value looks correct, and both an all-zero trace-id and an all-zero parent-id are explicitly invalid rather than empty.
- trace-flags is a bit field
- Bit 0 (mask 0x01) is sampled: set means the caller may have recorded trace data. Bit 1 (mask 0x02), introduced in Level 2, is random-trace-id: when set, at least the right-most 7 bytes of the trace-id must have been chosen randomly with uniform distribution, which lets downstream systems sample or shard on them. Bits 2 to 7 are reserved and must be ignored on receipt and cleared on outbound requests. Because reserved bits can be present, the field must be tested with a bitwise AND — an equality check against 0x01 misreports a sampled trace that also carries a reserved bit.
- Forward compatibility with future versions
- Version is 00 today and ff is forbidden, but a parser that rejects everything else is wrong. The specification asks receivers to attempt parsing when the version is higher and the header is at least as long as the known format, reading the fields they recognise and tolerating extra trailing data, rather than restarting the trace. This decoder follows that rule: a future version parses successfully and is flagged as a warning rather than an error.
- tracestate limits that bite in production
- At most 32 list-members — a hard grammatical bound, so a longer list makes the header invalid and receivers discard it. Each key is at most 256 characters and begins with a lowercase letter or digit; since Level 2 the @ is an ordinary key character rather than a tenant separator. Each value is 1 to 256 printable ASCII characters, never a comma or an equals sign. Duplicate keys are invalid, and empty list-members are explicitly allowed — a trailing comma left behind when an intermediary removes an entry is still a valid header. Separately, vendors should propagate at least 512 characters of the combined header; when they have to trim to stay inside that budget, entries longer than 128 characters should go first, which is why a verbose vendor's data disappears before a terse one's.
Trace Context Best Practices
- Test flags with a bitwise AND
- Write flags & 0x01 rather than flags == 0x01. Six of the eight bits are reserved for future use, and an equality check will start misreporting sampled traces the moment any of them appears in the wild.
- Treat an all-zero ID as a broken pipeline
- It is not an empty value to be tolerated. Reject the header, and go and find the component that failed to initialise its tracer or is injecting a placeholder.
- Look upstream when the sampled bit is clear
- Parent-based samplers propagate the caller's decision. If traces are missing, identify which service is sending you a parent span with sampling off before auditing your own configuration.
- Keep tracestate short
- The 32-member ceiling is a hard grammatical bound — exceed it and the header is invalid. Separately, only 512 characters of the combined header are guaranteed to propagate, and trimming drops entries over 128 characters first. Anything that must survive a long call chain does not belong in tracestate.
- Never log a trace ID as a JavaScript number
- A 128-bit trace ID and even a 64-bit Datadog identifier both exceed Number.MAX_SAFE_INTEGER. Keep them as strings, and convert with BigInt when you have to do arithmetic, or you will silently corrupt the last digits.
traceparent Decoder FAQ
What is the traceparent header?
What does traceparent trace-flags 00 mean?
What is the difference between trace-flags 01, 02 and 03?
Why is my trace ID all zeros?
How do I convert a W3C trace ID to a Datadog trace ID?
Does a traceparent contain a timestamp?
Is the header I paste here uploaded anywhere?
Does this decoder work offline?
Related Tools
View all tools →cURL Command Generator & Builder
Web & API
Build curl commands in your browser — set method, headers, auth, and body, get a copy-ready command instantly. Presets for Bearer, POST JSON, file upload. Free, private, no signup.
htpasswd Generator — bcrypt, Apache MD5 (apr1) & Basic Auth
Web & API
Generate htpasswd entries with bcrypt, Apache MD5 (apr1), SHA-1 & more. Get ready-to-paste Apache, nginx & Docker config. 100% in your browser — no upload.
Open Graph & Meta Tag Generator
Web & API
Generate Open Graph, Twitter Card & SEO meta tags with a live Google, Facebook & X preview. 100% free, in-browser, no signup — copy & paste the code.
Nginx Location Tester — Why That Block Wins
Web & API
See which nginx location block wins — and why every other block lost. Free location match tester for =, ^~, ~ and ~*, running entirely in your browser.
AES Decryption Tool — OpenSSL & CryptoJS Compatible
Security Tools
Decrypt AES online — GCM/CBC/CTR, passphrase or raw key, auto-detects OpenSSL & CryptoJS "U2FsdGVkX1" format. 100% in-browser, keys never leave the page.
AES Encryption Tool — GCM, CBC & CTR
Security Tools
Free online AES encryption — AES-128/192/256, GCM/CBC/CTR, passphrase (PBKDF2) or raw key. Runs 100% in your browser; nothing is uploaded.