The tracev3 File Format Explained
Inside macOS tracev3 files: header, catalog and LZ4 chunksets, firehose, oversize, statedump and simpledump chunks, uuidtext and dsc strings, and timesync.
TL;DR. A .tracev3 file is a stream of chunks. A header chunk describes the machine and boot, catalog chunks list the processes and subsystems, and each catalog is followed by chunksets — LZ4-compressed blocks holding firehose entries (the log messages), oversize strings, statedump and simpledump records. Text comes from uuidtext and dsc files, time from timesync. This is the structure the Unified Log Parser decodes, using Mandiant's open-source parser compiled to WebAssembly.
The layout below follows the public reverse-engineering work of Mandiant (macos-UnifiedLogs) and Joachim Metz (libyal dtformats). Apple does not document the format, and fields marked unknown in those sources are unknown here too.
Chunks and preambles
Every chunk starts with a 16-byte preamble: a 32-bit tag, a 32-bit sub-tag and a 64-bit data size. Chunks are padded to 8 bytes. The tags that matter:
| Tag | Chunk |
|---|---|
0x1000 | Header |
0x600b | Catalog |
0x600d | Chunkset (compressed) |
0x6001 | Firehose (inside a chunkset) |
0x6002 | Oversize (inside a chunkset) |
0x6003 | Statedump (inside a chunkset) |
0x6004 | Simpledump (inside a chunkset) |
A file therefore always begins with the bytes 00 10 00 00, which is how the parser recognises one whatever it is named.
Header
The header records the Mach timebase (numerator and denominator), the continuous time when the file was started, the time-zone bias and daylight-saving flag, and sub-chunks with the build version (for example 25G83), the hardware model (Mac14,14), the boot UUID, the PID of logd and the path of the time-zone file. The boot UUID ties every entry to a boot session and to the right timesync records. The parser's Sources tab shows these values.
Catalog
A catalog describes the entries of the chunksets that follow it:
- an array of UUIDs — of the binaries that logged and of the shared cache;
- a table of subsystem and category strings;
- process entries: PID, effective user ID, the index of the main executable UUID and of the shared-cache UUID, the extra UUIDs (loaded libraries) with their load addresses, and the subsystems the process used;
- subchunk descriptors: time span, uncompressed size and compression algorithm of each chunkset.
Firehose entries refer to their process through a pair of identifiers resolved in this table, and to their subsystem by a small index.
Chunksets
A chunkset is a compressed block. Most use LZ4 with Apple's bv41 block header (bv41- marks an uncompressed block); newer releases can also use LZBITMAP, which the parser supports. Decompressed, a chunkset is again a sequence of chunks.
Firehose
A firehose chunk has a preamble with a base continuous time, then entries. Each entry has an activity type (log, activity, trace, signpost, loss), a log type (Default, Info, Debug, Error, Fault, or a signpost kind), flags, a thread ID, a time delta and a data area. The flags say where the format string is: in the process's own uuidtext file (main executable), in the shared cache (dsc), at an absolute offset, or relative to another UUID. The data area holds the arguments — numbers, strings, or references to private data and oversize strings.
Oversize
Arguments too large for the entry are stored in oversize chunks, keyed by a data reference. They can sit in a later file than the entry that points to them, which is why a parser must carry oversize data across files and retry unresolved entries at the end.
Statedump and simpledump
Statedumps are snapshots a process writes on demand — a plist, a protobuf or a custom object with a title (the "TCC Authorization Cache" is one). Simpledumps are short messages logged by launchd and a few others without a format string.
uuidtext and dsc: the missing text
A uuidtext file (/private/var/db/uuidtext/XX/…, where XX is the first byte of the UUID and the file name is the remaining 30 hex digits) starts with the signature 0x66778899, lists ranges of the binary's address space, holds the corresponding format strings, and ends with the binary's path. A dsc file (uuidtext/dsc/<32 hex>, signature hcsd) does the same for the whole dyld shared cache and names each framework in it.
To render a message, the parser finds the right file from the catalog UUID and the entry flags, reads the format string at the recorded offset, and applies the arguments printf-style: %d, %s, %@, %{public}s, %{private}@ and type decoders such as %{errno}d, %{uuid_t}.16P or %{bool}d. Private arguments that were not captured come out as <private>.
timesync
timesync files hold, per boot UUID, a header (signature 0xbbb0, timebase, boot time) and records pairing a continuous time with a wall-clock time. The wall-clock time of an entry is the nearest preceding record's wall time plus the elapsed continuous time, multiplied by the timebase — 125/3 on Apple silicon, 1/1 on Intel.
What this means in practice
- Collect
uuidtext,dscandtimesyncwith the tracev3 files (collection guide). - Expect a few "unresolved" entries even then: a string may be missing from the files Apple kept.
- Compare important entries with
log show. Validated on a real archive, the parser rendered about 99% of log, activity and state messages identically; signposts differ in presentation.
See the glossary for the individual terms, or open your own files in the parser.