Summary

  • qlog can validate the structure of events that survived capture, but its own model permits Core events to be absent, early records to be overwritten and sensitive fields to be omitted or truncated.
  • A schema URI, ascending timestamp or clean connection-close event cannot prove that an unrecorded event did not occur, that two traces share one chronology or that the service outcome succeeded.
  • Operators need an evidence ledger for capture policy, omission, clock and vantage point, followed by independent outcome evidence and an authorized response.

The file ended elegantly. Its last event recorded a connection state transition, every required field parsed, the event name belonged to a recognized namespace, and the analysis tool drew an unbroken line to the final timestamp. On the incident bridge, that visual neatness acquired a stronger meaning: the connection had been observed from beginning to end.

It had not. The logger used a fixed-size circular buffer. As new events arrived, the oldest records—including connection setup—were overwritten. Nothing in the surviving trace marked the position of each displaced event. The final record was genuine. The inferred beginning was invented.

This is precisely the kind of distinction that draft-ietf-quic-qlog-main-schema-14 helps an organisation make. The July 2026 document is an active QUIC Working Group Internet-Draft intended for Proposed Standard, not an RFC. It defines a common architecture for structured protocol logs: files contain traces; traces carry metadata and events; events combine time, name and data; event schemas describe concrete namespaces and types. qlog can be serialized as JSON, JSON Text Sequences and other formats. Its value is interoperability: implementations and tools can share a vocabulary instead of translating proprietary logs before every investigation.

That common vocabulary standardizes the evidence that is present. It does not promise that every relevant observation is present.

A schema list is not an event inventory

Each trace lists one or more event_schemas URIs. It is tempting to read that list as a declaration of contents: if the QUIC schema is named, then all expected QUIC events must have been captured. The draft says otherwise. The field is a hint about possible namespaces and types. A trace may contain types from a schema it did not list. Conversely, it need not contain every event type associated with a schema it did list. Tools must not turn either condition into an error.

The importance hierarchy carries the same restraint. Core events should ordinarily be present for a protocol, Base events add debugging information, and Extra events expose finer implementation detail. Yet a tool should not expect every Core event in every trace. An implementation concerned about performance or privacy may omit data-rich Core records and log a relevant subset of Base events instead.

This makes absence a policy-dependent observation. “No packet_received event appears” can mean the packet was not received. It can also mean the logger was disabled, started late, sampled, exhausted its buffer, omitted the event class, substituted another event, failed before emission or intentionally minimized the record. A valid trace does not choose among those explanations.

TraceError does not close the gap. That object records a failed attempt to find or convert a particular file for inclusion in an aggregate. It prevents one known aggregation failure from disappearing silently. Its absence says nothing about inputs nobody enumerated, records overwritten inside a valid source trace or events a capture policy never asked the implementation to emit.

Format survival is not historical survival

The distinction becomes sharper during crashes. A normal JSON qlog is a complete document. If a process dies before appending its closing brackets, common parsers may reject it as malformed. qlog therefore also maps to JSON Text Sequences. In that form, each event is an individual record prefixed and terminated in a defined way. The records written before failure can be parsed independently.

That is valuable resilience. It is not a claim that the first event in the surviving stream was the first event in the connection, or that the final record captured the last causal act before failure. JSON-SEQ improves the odds that emitted records survive. It cannot recover a capture window that began late, a circular buffer that discarded history or a privacy rule that withheld content.

The same boundary applies to schema validation. A validator can establish that an event has the expected shape and allowed data types. It cannot validate the event that was never logged. Syntax is a receipt about the object in hand, not about the universe of missing objects.

Time needs a provenance chain of its own

Every qlog event carries a numeric time, but the draft deliberately supports different meanings. The reference clock may use system time, which can jump, or monotonic time, whose epoch is unknown. An optional wall-clock value can approximate when monotonic logging began, but the draft warns that it cannot safely anchor calendar conversion. Events within the same trace need not even use the same time format.

One compact format records each time relative to the previously logged event. That delta encoding is efficient, but interpretation depends on the retained sequence. The draft recommends ascending timestamp order while acknowledging that multithreaded and streaming loggers may need a post-processor. It also tells tools not to assume timestamps are consistent across traces, even when one endpoint generated them.

Consequently, two neat timelines are not automatically one incident timeline. A client trace, server trace and network observation come from different vantage points. Their direction fields, identifiers, capture windows, clock types and correlation uncertainty must be retained before an analyst can make a causal ordering claim. “A preceded B in this trace” is narrower than “A caused B across the service.”

The surviving length is only a length

qlog allows raw protocol information, but it does not require indiscriminate payload capture. RawInfo can retain a full byte length, a payload length and raw bytes independently. The bytes may be absent or truncated while the length still describes the original entity. This is a useful compromise: an operator can study sizes and framing without storing sensitive content.

It also creates a predictable inference error. If a 1,200-byte record survives but its bytes do not, the trace proves a reported size under the logger's semantics. It does not prove what the payload contained, whether an application accepted it, whether it was authorized or why the next event occurred. A dashboard that assigns meaning from length alone has crossed from evidence into conjecture.

The optional trigger field shows why local causality deserves care. Parallel implementations may separate related messages in time, so a nearby event can be a poor explanation. When a concrete event defines and records a trigger, that is stronger evidence. When it does not, an analyst should expose the uncertainty instead of borrowing causality from adjacency.

Completeness must be an explicit operational claim

An evidence-grade qlog programme needs a second ledger beside the trace. For each capture, record:

  1. who or what authorized it, for which purpose and retention period;
  2. the logger version, vantage point and actual capture window;
  3. serialization and schema versions;
  4. buffer size, overwrite state, sampling and event-importance policy;
  5. privacy filters, truncation and field-level omissions;
  6. clock type, reference time, time format and known synchronization error;
  7. event and byte counters before and after each processing stage;
  8. expected peer or network traces and any failed collection attempt;
  9. the analytical question the retained fields can answer; and
  10. the application or service evidence used to test the conclusion.

This is operator guidance, not a hidden requirement of qlog. Its purpose is to stop tools from silently promoting “valid,” “supported” or “ordered” into “complete.” An interface should label the evidence grade it actually has: parseable record, locally ordered trace, bounded capture window, correlated multi-vantage episode or application-confirmed outcome.

qlog's restraint is a strength. It gives running implementations room to balance diagnostic value, cost and privacy without pretending one capture profile suits every environment. The leadership mistake would be to erase that flexibility at the reporting layer and treat a standardized container as a standardized truth.

Sources