QUIC event definitions for qlog
draft-ietf-quic-qlog-quic-events-14
| Document | Type | Active Internet-Draft (quic WG) | |
|---|---|---|---|
| Authors | Robin Marx , Luca Niccolini , Marten Seemann , Lucas Pardue | ||
| Last updated | 2026-11-02 | ||
| Replaces | draft-marx-quic-qlog-quic-events | ||
| RFC stream | Internet Engineering Task Force (IETF) | ||
| Intended RFC status | Proposed Standard | ||
| Formats | |||
| Additional resources | Mailing list discussion | ||
| Stream | WG state | WG Document | |
| Associated WG milestone |
|
||
| On agenda | quic at IETF-127 | ||
| Document shepherd | (None) | ||
| IESG | IESG state | I-D Exists | |
| Consensus boilerplate | Yes | ||
| Telechat date | (None) | ||
| Responsible AD | (None) | ||
| Send notices to | (None) |
draft-ietf-quic-qlog-quic-events-14
QUIC R. Marx, Ed.
Internet-Draft Akamai
Intended status: Standards Track L. Niccolini, Ed.
Expires: 6 May 2027 Meta
M. Seemann, Ed.
L. Pardue, Ed.
Apple
2 November 2026
QUIC event definitions for qlog
draft-ietf-quic-qlog-quic-events-14
Abstract
This document describes a qlog event schema containing concrete qlog
event definitions and their metadata for the core QUIC protocol and
selected extensions.
Note to Readers
Note to RFC editor: Please remove this section before publication.
Feedback and discussion are welcome at https://github.com/quicwg/qlog
(https://github.com/quicwg/qlog). Readers are advised to refer to
the "editor's draft" at that URL for an up-to-date version of this
document.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 6 May 2027.
Marx, et al. Expires 6 May 2027 [Page 1]
Internet-Draft QUIC event definitions for qlog November 2026
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Use of Group IDs . . . . . . . . . . . . . . . . . . . . 5
1.2. Raw Packet and Frame Information . . . . . . . . . . . . 5
1.3. Events without a Known Connection . . . . . . . . . . . . 5
1.4. Notational Conventions . . . . . . . . . . . . . . . . . 6
2. Event Schema Definition . . . . . . . . . . . . . . . . . . . 6
2.1. Draft Event Schema Identification . . . . . . . . . . . . 6
3. QUIC Event Overview . . . . . . . . . . . . . . . . . . . . . 7
4. Connectivity Events . . . . . . . . . . . . . . . . . . . . . 10
4.1. server_listening . . . . . . . . . . . . . . . . . . . . 10
4.2. connection_started . . . . . . . . . . . . . . . . . . . 10
4.3. connection_closed . . . . . . . . . . . . . . . . . . . . 11
4.4. connection_id_updated . . . . . . . . . . . . . . . . . . 12
4.5. spin_bit_updated . . . . . . . . . . . . . . . . . . . . 13
4.6. connection_state_updated . . . . . . . . . . . . . . . . 13
4.7. tuple_assigned . . . . . . . . . . . . . . . . . . . . . 15
4.8. mtu_updated . . . . . . . . . . . . . . . . . . . . . . . 16
5. Transport Events . . . . . . . . . . . . . . . . . . . . . . 16
5.1. version_information . . . . . . . . . . . . . . . . . . . 16
5.2. alpn_information . . . . . . . . . . . . . . . . . . . . 17
5.3. parameters_set . . . . . . . . . . . . . . . . . . . . . 18
5.4. parameters_restored . . . . . . . . . . . . . . . . . . . 20
5.5. packet_sent . . . . . . . . . . . . . . . . . . . . . . . 21
5.6. packet_received . . . . . . . . . . . . . . . . . . . . . 22
5.7. packet_dropped . . . . . . . . . . . . . . . . . . . . . 23
5.8. packet_buffered . . . . . . . . . . . . . . . . . . . . . 25
5.9. packets_acked . . . . . . . . . . . . . . . . . . . . . . 25
5.10. udp_datagrams_sent . . . . . . . . . . . . . . . . . . . 26
5.11. udp_datagrams_received . . . . . . . . . . . . . . . . . 27
5.12. udp_datagram_dropped . . . . . . . . . . . . . . . . . . 27
5.13. stream_state_updated . . . . . . . . . . . . . . . . . . 28
5.14. Frame-Related Events . . . . . . . . . . . . . . . . . . 30
Marx, et al. Expires 6 May 2027 [Page 2]
Internet-Draft QUIC event definitions for qlog November 2026
5.14.1. frames_created . . . . . . . . . . . . . . . . . . . 31
5.14.2. frames_parsed . . . . . . . . . . . . . . . . . . . 31
5.15. stream_data_moved . . . . . . . . . . . . . . . . . . . . 31
5.16. datagram_data_moved . . . . . . . . . . . . . . . . . . . 32
5.17. datagram_dropped . . . . . . . . . . . . . . . . . . . . 33
5.18. connection_data_blocked_updated . . . . . . . . . . . . . 34
5.19. stream_data_blocked_updated . . . . . . . . . . . . . . . 35
5.20. datagram_data_blocked_updated . . . . . . . . . . . . . . 35
5.21. migration_state_updated . . . . . . . . . . . . . . . . . 35
5.22. timer_updated . . . . . . . . . . . . . . . . . . . . . . 37
6. Security Events . . . . . . . . . . . . . . . . . . . . . . . 38
6.1. key_updated . . . . . . . . . . . . . . . . . . . . . . . 38
6.2. key_discarded . . . . . . . . . . . . . . . . . . . . . . 39
7. Recovery Events . . . . . . . . . . . . . . . . . . . . . . . 40
7.1. recovery_parameters_set . . . . . . . . . . . . . . . . . 40
7.2. recovery_metrics_updated . . . . . . . . . . . . . . . . 41
7.3. congestion_state_updated . . . . . . . . . . . . . . . . 43
7.4. packet_lost . . . . . . . . . . . . . . . . . . . . . . . 43
7.5. marked_for_retransmit . . . . . . . . . . . . . . . . . . 44
7.6. ecn_state_updated . . . . . . . . . . . . . . . . . . . . 45
8. QUIC Data Type Definitions . . . . . . . . . . . . . . . . . 45
8.1. QuicVersion . . . . . . . . . . . . . . . . . . . . . . . 45
8.2. ConnectionID . . . . . . . . . . . . . . . . . . . . . . 46
8.3. Initiator . . . . . . . . . . . . . . . . . . . . . . . . 46
8.4. IPAddressPort . . . . . . . . . . . . . . . . . . . . . . 46
8.5. TupleEndpointInfo . . . . . . . . . . . . . . . . . . . . 46
8.6. PacketType . . . . . . . . . . . . . . . . . . . . . . . 47
8.7. PacketNumberSpace . . . . . . . . . . . . . . . . . . . . 47
8.8. PacketHeader . . . . . . . . . . . . . . . . . . . . . . 47
8.9. Token . . . . . . . . . . . . . . . . . . . . . . . . . . 49
8.10. StatelessResetToken . . . . . . . . . . . . . . . . . . . 49
8.11. KeyType . . . . . . . . . . . . . . . . . . . . . . . . . 49
8.12. ECN . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
8.13. QUIC Frames . . . . . . . . . . . . . . . . . . . . . . . 50
8.13.1. PaddingFrame . . . . . . . . . . . . . . . . . . . . 51
8.13.2. PingFrame . . . . . . . . . . . . . . . . . . . . . 51
8.13.3. AckFrame . . . . . . . . . . . . . . . . . . . . . . 52
8.13.4. ResetStreamFrame . . . . . . . . . . . . . . . . . . 52
8.13.5. ResetStreamAtFrame . . . . . . . . . . . . . . . . . 53
8.13.6. StopSendingFrame . . . . . . . . . . . . . . . . . . 53
8.13.7. CryptoFrame . . . . . . . . . . . . . . . . . . . . 54
8.13.8. NewTokenFrame . . . . . . . . . . . . . . . . . . . 54
8.13.9. StreamFrame . . . . . . . . . . . . . . . . . . . . 54
8.13.10. MaxDataFrame . . . . . . . . . . . . . . . . . . . . 55
8.13.11. MaxStreamDataFrame . . . . . . . . . . . . . . . . . 55
8.13.12. MaxStreamsFrame . . . . . . . . . . . . . . . . . . 55
8.13.13. DataBlockedFrame . . . . . . . . . . . . . . . . . . 55
8.13.14. StreamDataBlockedFrame . . . . . . . . . . . . . . . 56
Marx, et al. Expires 6 May 2027 [Page 3]
Internet-Draft QUIC event definitions for qlog November 2026
8.13.15. StreamsBlockedFrame . . . . . . . . . . . . . . . . 56
8.13.16. NewConnectionIDFrame . . . . . . . . . . . . . . . . 56
8.13.17. RetireConnectionIDFrame . . . . . . . . . . . . . . 57
8.13.18. PathChallengeFrame . . . . . . . . . . . . . . . . . 57
8.13.19. PathResponseFrame . . . . . . . . . . . . . . . . . 57
8.13.20. ConnectionCloseFrame . . . . . . . . . . . . . . . . 57
8.13.21. HandshakeDoneFrame . . . . . . . . . . . . . . . . . 58
8.13.22. UnknownFrame . . . . . . . . . . . . . . . . . . . . 58
8.13.23. DatagramFrame . . . . . . . . . . . . . . . . . . . 59
8.14. TransportError . . . . . . . . . . . . . . . . . . . . . 59
8.15. ApplicationError . . . . . . . . . . . . . . . . . . . . 60
8.16. CryptoError . . . . . . . . . . . . . . . . . . . . . . . 60
9. Handling Packet Coalescing . . . . . . . . . . . . . . . . . 61
10. Security and Privacy Considerations . . . . . . . . . . . . . 61
11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 61
12. References . . . . . . . . . . . . . . . . . . . . . . . . . 62
12.1. Normative References . . . . . . . . . . . . . . . . . . 62
12.2. Informative References . . . . . . . . . . . . . . . . . 63
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 63
Change Log . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Since draft-ietf-qlog-quic-events-13: . . . . . . . . . . . . . 64
Since draft-ietf-qlog-quic-events-12: . . . . . . . . . . . . . 64
Since draft-ietf-qlog-quic-events-11: . . . . . . . . . . . . . 64
Since draft-ietf-qlog-quic-events-09: . . . . . . . . . . . . . 64
Since draft-ietf-qlog-quic-events-08: . . . . . . . . . . . . . 64
Since draft-ietf-qlog-quic-events-07: . . . . . . . . . . . . . 65
Since draft-ietf-qlog-quic-events-06: . . . . . . . . . . . . . 65
Since draft-ietf-qlog-quic-events-05: . . . . . . . . . . . . . 65
Since draft-ietf-qlog-quic-events-04: . . . . . . . . . . . . . 65
Since draft-ietf-qlog-quic-events-03: . . . . . . . . . . . . . 66
Since draft-ietf-qlog-quic-events-02: . . . . . . . . . . . . . 66
Since draft-ietf-qlog-quic-events-01: . . . . . . . . . . . . . 67
Since draft-ietf-qlog-quic-events-00: . . . . . . . . . . . . . 67
Since draft-marx-qlog-event-definitions-quic-h3-02: . . . . . . 67
Since draft-marx-qlog-event-definitions-quic-h3-01: . . . . . . 67
Since draft-marx-qlog-event-definitions-quic-h3-00: . . . . . . 68
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 69
1. Introduction
This document defines a qlog event schema (Section 8 of [QLOG-MAIN])
containing concrete events for the core QUIC protocol (see
[QUIC-TRANSPORT], [QUIC-RECOVERY], and [QUIC-TLS]) and some of its
extensions (see [QUIC-DATAGRAM], [GREASEBIT], and [RESET-STREAM-AT]).
Marx, et al. Expires 6 May 2027 [Page 4]
Internet-Draft QUIC event definitions for qlog November 2026
The event namespace with identifier quic is defined; see Section 2.
In this namespace multiple events derive from the qlog abstract Event
class (Section 7 of [QLOG-MAIN]), each extending the data field and
defining their name field values and semantics. The data types that
the events use are defined in Section 8.
1.1. Use of Group IDs
QUIC's Original Destination Connection ID (ODCID) can be used as the
value of the qlog group_id field. The ODCID is the connection ID
that the client chooses for its first Initial packet. It stays the
same for the whole connection, unlike the connection IDs that
endpoints use, which can change. It can also link packets such as
Retry and Version Negotiation to the connection.
The ODCID can also be used as the qlog filename or file identifier,
optionally suffixed by the vantage point type. For example,
abcd1234_server.qlog would contain the server-side trace of the
connection with ODCID abcd1234.
1.2. Raw Packet and Frame Information
Protected QUIC packets (Initial, 0-RTT, Handshake, and 1-RTT) end
with an AEAD authentication tag. Every cipher suite that QUIC
version 1 can use has a 16-byte tag; see Section 5.3 of [QUIC-TLS].
When calculating the lengths in RawInfo fields (Section 10 of
[QLOG-MAIN]) for these packets, the tag is treated as a 16-byte
trailer.
1.3. Events without a Known Connection
A qlog trace is typically associated with a single QUIC connection.
However, some events cannot be tied to a specific connection,
especially on the server. For example, a packet_dropped event
(Section 5.7) with the trigger "connection_unknown" is for a packet
that matches no known connection.
There are various ways to handle these events, each with tradeoffs
between file size overhead, flexibility, ease of use, and ease of
implementation. Some options include:
* Log them in a separate endpoint-wide trace, or use a special
group_id value, not associated with a single connection.
* Log them in the most recently used trace.
* Use additional heuristics to identify the connection, for example
the four-tuple in addition to the connection ID.
Marx, et al. Expires 6 May 2027 [Page 5]
Internet-Draft QUIC event definitions for qlog November 2026
* Buffer events until they can be assigned to a connection, for
example events about the Version Negotiation and Retry packets
that a server sends before it creates connection state.
1.4. Notational Conventions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" 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.
The event and data structure definitions in this document are
expressed in the Concise Data Definition Language [CDDL] and its
extensions described in Section 1.2 of [QLOG-MAIN].
This document uses the following from [QLOG-MAIN]: the event
namespace and event type concepts; the name, data, tuple, group_id,
and time-related fields; and the RawInfo type.
Events are defined with an importance level as described in
Section 8.3 of [QLOG-MAIN].
As is the case for [QLOG-MAIN], the qlog schema definitions in this
document are intentionally agnostic to serialization formats. The
choice of format is an implementation decision.
2. Event Schema Definition
This document describes how the core QUIC protocol and selected
extensions can be expressed in qlog using a newly defined event
schema. Per the requirements in Section 8 of [QLOG-MAIN], this
document registers the quic namespace. The event schema URI is
urn:ietf:params:qlog:events:quic.
2.1. Draft Event Schema Identification
This section is to be removed before publishing as an RFC.
Only implementations of the final, published RFC can use the events
belonging to the event schema with the URI
urn:ietf:params:qlog:events:quic. Until such an RFC exists,
implementations MUST NOT identify themselves using this URI.
Implementations of draft versions of the event schema MUST append the
string "-" and the corresponding draft number to the URI. For
example, draft 07 of this document is identified using the URI
urn:ietf:params:qlog:events:quic-07.
Marx, et al. Expires 6 May 2027 [Page 6]
Internet-Draft QUIC event definitions for qlog November 2026
The namespace identifier itself is not affected by this requirement.
3. QUIC Event Overview
Table 1 summarizes the name value of each event type that is defined
in this specification.
+======================================+============+==============+
| Name value | Importance | Definition |
+======================================+============+==============+
| quic:server_listening | Extra | Section 4.1 |
+--------------------------------------+------------+--------------+
| quic:connection_started | Base | Section 4.2 |
+--------------------------------------+------------+--------------+
| quic:connection_closed | Base | Section 4.3 |
+--------------------------------------+------------+--------------+
| quic:connection_id_updated | Base | Section 4.4 |
+--------------------------------------+------------+--------------+
| quic:spin_bit_updated | Base | Section 4.5 |
+--------------------------------------+------------+--------------+
| quic:connection_state_updated | Base | Section 4.6 |
+--------------------------------------+------------+--------------+
| quic:tuple_assigned | Base | Section 4.7 |
+--------------------------------------+------------+--------------+
| quic:mtu_updated | Extra | Section 4.8 |
+--------------------------------------+------------+--------------+
| quic:version_information | Core | Section 5.1 |
+--------------------------------------+------------+--------------+
| quic:alpn_information | Core | Section 5.2 |
+--------------------------------------+------------+--------------+
| quic:parameters_set | Core | Section 5.3 |
+--------------------------------------+------------+--------------+
| quic:parameters_restored | Base | Section 5.4 |
+--------------------------------------+------------+--------------+
| quic:packet_sent | Core | Section 5.5 |
+--------------------------------------+------------+--------------+
| quic:packet_received | Core | Section 5.6 |
+--------------------------------------+------------+--------------+
| quic:packet_dropped | Base | Section 5.7 |
+--------------------------------------+------------+--------------+
| quic:packet_buffered | Base | Section 5.8 |
+--------------------------------------+------------+--------------+
| quic:packets_acked | Extra | Section 5.9 |
+--------------------------------------+------------+--------------+
| quic:udp_datagrams_sent | Extra | Section 5.10 |
+--------------------------------------+------------+--------------+
| quic:udp_datagrams_received | Extra | Section 5.11 |
+--------------------------------------+------------+--------------+
Marx, et al. Expires 6 May 2027 [Page 7]
Internet-Draft QUIC event definitions for qlog November 2026
| quic:udp_datagram_dropped | Extra | Section 5.12 |
+--------------------------------------+------------+--------------+
| quic:stream_state_updated | Base | Section 5.13 |
+--------------------------------------+------------+--------------+
| quic:frames_created | Extra | Section |
| | | 5.14.1 |
+--------------------------------------+------------+--------------+
| quic:frames_parsed | Extra | Section |
| | | 5.14.2 |
+--------------------------------------+------------+--------------+
| quic:stream_data_moved | Base | Section 5.15 |
+--------------------------------------+------------+--------------+
| quic:datagram_data_moved | Base | Section 5.16 |
+--------------------------------------+------------+--------------+
| quic:datagram_dropped | Base | Section 5.17 |
+--------------------------------------+------------+--------------+
| quic:connection_data_blocked_updated | Extra | Section 5.18 |
+--------------------------------------+------------+--------------+
| quic:stream_data_blocked_updated | Extra | Section 5.19 |
+--------------------------------------+------------+--------------+
| quic:datagram_data_blocked_updated | Extra | Section 5.20 |
+--------------------------------------+------------+--------------+
| quic:migration_state_updated | Extra | Section 5.21 |
+--------------------------------------+------------+--------------+
| quic:timer_updated | Extra | Section 5.22 |
+--------------------------------------+------------+--------------+
| quic:key_updated | Base | Section 6.1 |
+--------------------------------------+------------+--------------+
| quic:key_discarded | Base | Section 6.2 |
+--------------------------------------+------------+--------------+
| quic:recovery_parameters_set | Base | Section 7.1 |
+--------------------------------------+------------+--------------+
| quic:recovery_metrics_updated | Core | Section 7.2 |
+--------------------------------------+------------+--------------+
| quic:congestion_state_updated | Base | Section 7.3 |
+--------------------------------------+------------+--------------+
| quic:packet_lost | Core | Section 7.4 |
+--------------------------------------+------------+--------------+
| quic:marked_for_retransmit | Extra | Section 7.5 |
+--------------------------------------+------------+--------------+
| quic:ecn_state_updated | Extra | Section 7.6 |
+--------------------------------------+------------+--------------+
Table 1: QUIC Events
Marx, et al. Expires 6 May 2027 [Page 8]
Internet-Draft QUIC event definitions for qlog November 2026
QUIC events extend the $ProtocolEventData extension point defined in
Section 8.2 of [QLOG-MAIN]. Additionally, they allow for direct
extensibility by their use of per-event extension points via the $$
CDDL "group socket" syntax, as also described in Section 8.2 of
[QLOG-MAIN].
QuicEventData = QUICServerListening /
QUICConnectionStarted /
QUICConnectionClosed /
QUICConnectionIDUpdated /
QUICSpinBitUpdated /
QUICConnectionStateUpdated /
QUICTupleAssigned /
QUICMTUUpdated /
QUICVersionInformation /
QUICALPNInformation /
QUICParametersSet /
QUICParametersRestored /
QUICPacketSent /
QUICPacketReceived /
QUICPacketDropped /
QUICPacketBuffered /
QUICPacketsAcked /
QUICUDPDatagramsSent /
QUICUDPDatagramsReceived /
QUICUDPDatagramDropped /
QUICStreamStateUpdated /
QUICFramesCreated /
QUICFramesParsed /
QUICStreamDataMoved /
QUICDatagramDataMoved /
QUICDatagramDropped /
QUICConnectionDataBlockedUpdated /
QUICStreamDataBlockedUpdated /
QUICDatagramDataBlockedUpdated /
QUICMigrationStateUpdated /
QUICTimerUpdated /
QUICKeyUpdated /
QUICKeyDiscarded /
QUICRecoveryParametersSet /
QUICRecoveryMetricsUpdated /
QUICCongestionStateUpdated /
QUICPacketLost /
QUICMarkedForRetransmit /
QUICECNStateUpdated
$ProtocolEventData /= QuicEventData
Marx, et al. Expires 6 May 2027 [Page 9]
Internet-Draft QUIC event definitions for qlog November 2026
Figure 1: QuicEventData definition and ProtocolEventData extension
The concrete QUIC event types are further defined below, their type
identifier is the heading name. The subdivisions in sections on
Connectivity, Transport, Security, and Recovery are purely for
readability.
4. Connectivity Events
4.1. server_listening
The server_listening event is emitted when the server starts
accepting connections. It has Extra importance level.
QUICServerListening = {
? address_v4: IPAddressPort
? address_v6: IPAddressPort
; the server will always answer client Initial packets with a Retry
; packet (no 1-RTT connection setups by choice)
? retry_required: bool
* $$quic-serverlistening-extension
}
Figure 2: QUICServerListening definition
Some QUIC stacks do not handle sockets directly, so they cannot log
IP addresses or ports.
4.2. connection_started
The connection_started event is emitted when a client attempts a new
connection, or when a server accepts one. It overlaps with the
connection_state_updated event, but it also logs the local and remote
endpoint information. It has Base importance level.
QUICConnectionStarted = {
local: TupleEndpointInfo
remote: TupleEndpointInfo
* $$quic-connectionstarted-extension
}
Figure 3: QUICConnectionStarted definition
Marx, et al. Expires 6 May 2027 [Page 10]
Internet-Draft QUIC event definitions for qlog November 2026
Some QUIC stacks do not handle sockets directly, so they cannot log
IP addresses or ports. All fields of TupleEndpointInfo (Figure 45)
are optional, so such a stack can log local and remote with only the
fields it knows, such as connection_ids.
4.3. connection_closed
The connection_closed event is emitted when a connection closes,
typically because of an error or a timeout. It has Base importance
level.
This event overlaps with the connection_state_updated event and the
CONNECTION_CLOSE frame. However, when analyzing large deployments,
it can be useful to have a single event for each closure, with a
reason field for more detail. This event can also log closures due
to timeouts or explicit application actions, such as racing several
connections and aborting the slowest, which the other events cannot
easily capture.
The connection_closed event is logged when the local endpoint does
one of the following; see Section 10 of [QUIC-TRANSPORT]:
* silently discards the connection after an idle timeout;
* sends a CONNECTION_CLOSE frame, and enters the closing state;
* receives a CONNECTION_CLOSE frame, and enters the draining state;
or
* receives a Stateless Reset, and enters the draining state.
Later changes, such as leaving the closing or draining state, are
logged with the connection_state_updated event.
QUIC has two kinds of connection error, transport errors and
application errors, each with defined codes and semantics; see
Section 20 of [QUIC-TRANSPORT]. An implementation can also have
internal errors, which it might or might not map to these codes. So
this event can carry two levels of error: connection_error or
application_error for the QUIC error, and internal_code for a more
specific internal error.
If an error code has no known string, connection_error or
application_error can be "unknown", and error_code then holds the
numerical value without variable-length integer encoding.
Marx, et al. Expires 6 May 2027 [Page 11]
Internet-Draft QUIC event definitions for qlog November 2026
QUICConnectionClosed = {
; which side closed the connection
? initiator: Initiator
? connection_error: $TransportError /
CryptoError
? application_error: $ApplicationError
; if connection_error or application_error === "unknown"
? error_code: uint64
? internal_code: uint64
? reason: text
? trigger:
"idle_timeout" /
"application" /
"error" /
"version_mismatch" /
; when received from peer
"stateless_reset" /
"aborted" /
; when it is unclear what triggered the CONNECTION_CLOSE
"unspecified"
* $$quic-connectionclosed-extension
}
Figure 4: QUICConnectionClosed definition
Implementations SHOULD use the most descriptive trigger value that
they can determine. This is often clear at the endpoint that closes
the connection, but can be less clear at the endpoint that receives
the CONNECTION_CLOSE frame.
4.4. connection_id_updated
The connection_id_updated event is emitted when either endpoint
updates its current connection ID. This typically happens rarely
during a connection, so logging this event is more efficient than
logging the connection ID in every packet_sent or packet_received
event. It has Base importance level.
The connection_id_updated event is viewed from the perspective of the
endpoint applying the new ID. When the endpoint receives a new
connection ID from the peer, the initiator field is "remote". When
the endpoint updates its own connection ID, the initiator field is
"local".
Marx, et al. Expires 6 May 2027 [Page 12]
Internet-Draft QUIC event definitions for qlog November 2026
QUICConnectionIDUpdated = {
initiator: Initiator
? old: ConnectionID
? new: ConnectionID
* $$quic-connectionidupdated-extension
}
Figure 5: QUICConnectionIDUpdated definition
4.5. spin_bit_updated
The spin_bit_updated event is emitted when the value of the QUIC
latency spin bit changes; see Section 17.4 of [QUIC-TRANSPORT]. It
SHOULD NOT be emitted when the spin bit is set to the value it
already has. It has Base importance level.
QUICSpinBitUpdated = {
state: bool
* $$quic-spinbitupdated-extension
}
Figure 6: QUICSpinBitUpdated definition
4.6. connection_state_updated
The connection_state_updated event is emitted when the connection
changes state, to track progress through the QUIC handshake and
connection close. It has Base importance level.
[QUIC-TRANSPORT] does not define a complete set of connection states
or their transitions, though it names some, such as the closing and
draining states. This document defines the states most likely to be
useful for debugging QUIC connections; the list is not exhaustive.
QUIC implementations SHOULD log the BaseConnectionStates, and can add
the GranularConnectionStates when more in-depth debugging is
required. Tools SHOULD handle both kinds equally.
QUICConnectionStateUpdated = {
? old: $ConnectionState
new: $ConnectionState
* $$quic-connectionstateupdated-extension
}
BaseConnectionStates =
Marx, et al. Expires 6 May 2027 [Page 13]
Internet-Draft QUIC event definitions for qlog November 2026
; Initial packet sent/received
"attempted" /
; Handshake packet sent/received
"handshake_started" /
; Both sent a TLS Finished message
; and verified the peer's TLS Finished message
; 1-RTT packets can be sent
; RFC 9001 Section 4.1.1
"handshake_complete" /
; CONNECTION_CLOSE sent/received,
; stateless reset received or idle timeout
"closed"
GranularConnectionStates =
; RFC 9000 Section 8.1
; client sent Handshake packet OR
; client used connection ID chosen by the server OR
; client used valid address validation token
"peer_validated" /
; 1-RTT data can be sent by the server,
; but handshake is not done yet
; (server has sent TLS Finished; sometimes called 0.5 RTT data)
"early_write" /
; HANDSHAKE_DONE sent/received.
; RFC 9001 Section 4.1.2
"handshake_confirmed" /
; CONNECTION_CLOSE sent
"closing" /
; CONNECTION_CLOSE or Stateless Reset received
"draining" /
; draining or closing period done, connection state discarded
"closed"
$ConnectionState /= BaseConnectionStates / GranularConnectionStates
Figure 7: QUICConnectionStateUpdated definition
The connection_state_updated event overlaps with the
connection_closed and connection_started events, and with the frames
logged in events such as packet_received. Still, it can be useful to
Marx, et al. Expires 6 May 2027 [Page 14]
Internet-Draft QUIC event definitions for qlog November 2026
log state transitions separately, especially if they map to an
internal state machine. Implementations can therefore use other
ConnectionState values that match their internal logic. Tools SHOULD
handle these custom states in a similar way to the states defined in
this document.
4.7. tuple_assigned
The tuple_assigned event associates a TupleID with the details of a
network tuple, such as its IP addresses, ports, and connection IDs.
It has Base importance level.
As described in Section 7.2 of [QLOG-MAIN], each qlog event can be
linked to a single network tuple by its top-level tuple field, whose
value is a TupleID. Encoding tuple details, such as IP addresses or
connection IDs, into the TupleID itself can be cumbersome. This
event records them separately, so TupleIDs can stay short, and their
details can be updated as the connection evolves.
QUICTupleAssigned = {
tuple_id: TupleID
; the information for traffic going towards the remote receiver
? tuple_remote: TupleEndpointInfo
; the information for traffic coming in at the local endpoint
? tuple_local: TupleEndpointInfo
* $$quic-tupleassigned-extension
}
Figure 8: QUICTupleAssigned definition
Implementations choose their own tuple_id values. For example, a
TupleID can be an incrementing integer, the first Destination
Connection ID associated with the tuple (or its sequence number), or
the two endpoint IP addresses or a hash of them.
The empty string ("") is a valid TupleID, and it is the default for
events that do not set the tuple field. So the initial tuple of a
QUIC connection, on which the handshake occurs (see Section 4.2), is
implicitly associated with the TupleID "". Details for this default
tuple can be logged with a tuple_assigned event whose tuple_id is "".
Marx, et al. Expires 6 May 2027 [Page 15]
Internet-Draft QUIC event definitions for qlog November 2026
Because a tuple's details can change during the connection, a TupleID
can appear in several tuple_assigned events, and the latest one holds
its current details. The first tuple_assigned event for a TupleID
indicates that the TupleID was created, and later ones indicate
updates. An event with both tuple_local and tuple_remote omitted
indicates that the TupleID was abandoned.
4.8. mtu_updated
The mtu_updated event indicates that the estimated Path MTU was
updated. This happens as part of Path MTU discovery; see Section 14
of [QUIC-TRANSPORT]. It has Extra importance level.
QUICMTUUpdated = {
? old: uint32
new: uint32
; at some point, MTU discovery stops, as a "good enough"
; packet size has been found
? done: bool
* $$quic-mtuupdated-extension
}
Figure 9: QUICMTUUpdated definition
The done field defaults to false.
5. Transport Events
5.1. version_information
The version_information event supports QUIC version negotiation; see
Section 6 of [QUIC-TRANSPORT]. It has Core importance level.
Each QUIC endpoint supports one or more versions. The client sends
its first Initial packet using one of them. A server that does not
support that version can reply with a Version Negotiation packet,
which lists the versions the server supports. This event records the
versions that each endpoint supports, and the chosen version if there
is one.
Marx, et al. Expires 6 May 2027 [Page 16]
Internet-Draft QUIC event definitions for qlog November 2026
QUICVersionInformation = {
? server_versions: [+ QuicVersion]
? client_versions: [+ QuicVersion]
? chosen_version: QuicVersion
* $$quic-versioninformation-extension
}
Figure 10: QUICVersionInformation definition
A client logs this event when it sends its first Initial packet. The
event includes client_versions, and chosen_version holds the version
used in that packet.
If the client then processes a Version Negotiation packet, it logs
this event again with client_versions. The event also includes
server_versions, which holds the versions from that packet. If the
client selects one of them, chosen_version holds it; otherwise,
chosen_version is absent.
A Version Negotiation packet can also list reserved versions, which
an endpoint adds to check that its peer ignores unknown versions; see
Section 6.3 of [QUIC-TRANSPORT]. Because server_versions holds the
versions from the packet, it can include reserved versions.
A server logs this event when it receives a client's first Initial
packet. The event includes server_versions. If the server supports
the client's version, chosen_version holds the version that the
server uses for the connection. Otherwise, chosen_version is absent,
and client_versions holds the version the client used.
5.2. alpn_information
The alpn_information event supports Application-Layer Protocol
Negotiation (ALPN) over the QUIC transport; see [RFC7301] and
Section 8.1 of [QUIC-TLS]. It has Core importance level.
QUIC endpoints are configured with a list of supported ALPN
identifiers. During the TLS handshake, the client sends its list,
and the server chooses one identifier from both lists and sends it
back. If no match is found, the connection is closed.
ALPN identifiers are byte sequences, which are often valid UTF-8.
The ALPNIdentifier type can hold either form: byte_value holds the
raw bytes, and string_value holds the identifier as text.
Implementations SHOULD log at least one form and MAY log both.
Marx, et al. Expires 6 May 2027 [Page 17]
Internet-Draft QUIC event definitions for qlog November 2026
QUICALPNInformation = {
? server_alpns: [* ALPNIdentifier]
? client_alpns: [* ALPNIdentifier]
? chosen_alpn: ALPNIdentifier
* $$quic-alpninformation-extension
}
ALPNIdentifier = {
? byte_value: hexstring
? string_value: text
}
Figure 11: QUICALPNInformation definition
A client usually logs this event twice: first with client_alpns when
it offers its list, then with chosen_alpn when it learns the server's
choice. It can instead log a single event with both fields once it
learns the choice.
A server logs this event once, after it chooses, with client_alpns,
server_alpns, and chosen_alpn.
5.3. parameters_set
The parameters_set event groups settings from several sources, such
as transport parameters and the TLS cipher suite, into a single
event. This keeps the number of events low, and lets a reader reason
about what the settings do without needing to know which mechanism
set each one. It has Core importance level.
Most of these settings are set once and never change. However, they
are often set at different times during the connection, so a trace
can contain several parameters_set events with different fields set.
Some settings have two values: one set by the local endpoint, and one
requested by the peer. The initiator field says which side the
settings in an event come from, so it MUST be correct for every
setting in that event. Local and remote settings MUST be logged in
separate events. If the local endpoint changes its behavior based on
the peer's settings, the outcome can be logged with a new event type,
or with fields added through $$quic-parametersset-extension; see
Section 8.2 of [QLOG-MAIN].
The initiator field is required. Settings that both endpoints
negotiate, such as tls_cipher, are logged in both the local and the
remote event.
Marx, et al. Expires 6 May 2027 [Page 18]
Internet-Draft QUIC event definitions for qlog November 2026
Each setting starts the connection with its default value, or with no
value if it has no default. A parameters_set event that includes a
setting replaces its previous value; settings that the event omits
keep their values.
The grease_quic_bit and reset_stream_at settings are true if the
transport parameter is present, and default to false.
Implementations are not required to recognize, process, or support
every parameter that they receive. For example, QUIC implementations
ignore transport parameters that they do not support; see
Section 7.4.2 of [QUIC-TRANSPORT]. The unknown_parameters field can
log the raw values of such parameters, for example reserved (GREASE)
parameters, private extensions, or experiments.
In the case of connection resumption and 0-RTT, some of the server's
parameters are stored up-front at the client and used for the initial
connection startup. They are later updated with the server's reply.
In these cases, utilize the separate parameters_restored event to
indicate the initial values, and this event to indicate the updated
values, as normal.
QUICParametersSet = {
initiator: Initiator
; true if valid session ticket was received
? resumption_allowed: bool
; true if early data extension was enabled on the TLS layer
? early_data_enabled: bool
; e.g., "AES_128_GCM_SHA256"
? tls_cipher: text
; RFC9000
? original_destination_connection_id: ConnectionID
? initial_source_connection_id: ConnectionID
? retry_source_connection_id: ConnectionID
? stateless_reset_token: StatelessResetToken
? disable_active_migration: bool
? max_idle_timeout: uint64
? max_udp_payload_size: uint64
? ack_delay_exponent: uint64
? max_ack_delay: uint64
? active_connection_id_limit: uint64
? initial_max_data: uint64
? initial_max_stream_data_bidi_local: uint64
? initial_max_stream_data_bidi_remote: uint64
Marx, et al. Expires 6 May 2027 [Page 19]
Internet-Draft QUIC event definitions for qlog November 2026
? initial_max_stream_data_uni: uint64
? initial_max_streams_bidi: uint64
? initial_max_streams_uni: uint64
? preferred_address: PreferredAddress
? unknown_parameters: [* UnknownParameter]
; RFC9221
? max_datagram_frame_size: uint64
; RFC9287
? grease_quic_bit: bool
; draft-ietf-quic-reliable-stream-reset
? reset_stream_at: bool
* $$quic-parametersset-extension
}
PreferredAddress = {
? address_v4: IPAddressPort
? address_v6: IPAddressPort
connection_id: ConnectionID
stateless_reset_token: StatelessResetToken
}
UnknownParameter = {
id: uint64
? value: hexstring
}
Figure 12: QUICParametersSet definition
5.4. parameters_restored
When using QUIC 0-RTT, clients are expected to remember and restore
the server's transport parameters from the previous connection. The
parameters_restored event is used to indicate which parameters were
restored and to which values when utilizing 0-RTT. It has Base
importance level.
Note that not all transport parameters should be restored (many are
even prohibited from being re-utilized). The ones listed here are
the ones expected to be useful for correct 0-RTT usage.
Marx, et al. Expires 6 May 2027 [Page 20]
Internet-Draft QUIC event definitions for qlog November 2026
QUICParametersRestored = {
; RFC9000
? disable_active_migration: bool
? max_idle_timeout: uint64
? max_udp_payload_size: uint64
? active_connection_id_limit: uint64
? initial_max_data: uint64
? initial_max_stream_data_bidi_local: uint64
? initial_max_stream_data_bidi_remote: uint64
? initial_max_stream_data_uni: uint64
? initial_max_streams_bidi: uint64
? initial_max_streams_uni: uint64
; RFC9221
? max_datagram_frame_size: uint64
; RFC9287
; can only be restored at the client.
; servers MUST NOT restore this parameter!
? grease_quic_bit: bool
* $$quic-parametersrestored-extension
}
Figure 13: QUICParametersRestored definition
5.5. packet_sent
The packet_sent event indicates that a QUIC packet was sent. It has
Core importance level.
Marx, et al. Expires 6 May 2027 [Page 21]
Internet-Draft QUIC event definitions for qlog November 2026
QUICPacketSent = {
header: PacketHeader
? frames: [* $QuicFrame]
; only if header.packet_type === "stateless_reset"
? stateless_reset_token: StatelessResetToken
; only if header.packet_type === "version_negotiation"
? supported_versions: [+ QuicVersion]
? raw: RawInfo
? datagram_payload_checksum: uint32
? is_mtu_probe_packet: bool
? trigger:
; RFC 9002 Section 6.1.1
"retransmit_reordered" /
; RFC 9002 Section 6.1.2
"retransmit_timeout" /
; RFC 9002 Section 6.2.4
"pto_probe" /
; RFC 9002 6.2.3
"retransmit_crypto" /
; needed for some CCs to figure out bandwidth allocations
; when there are no normal sends
"cc_bandwidth_probe"
* $$quic-packetsent-extension
}
Figure 14: QUICPacketSent definition
The encryption level and packet number space are not logged
explicitly, because header.packet_type implies them for the packet
types that have them.
The datagram_payload_checksum field is described in Section 9.
The is_mtu_probe_packet field defaults to false.
5.6. packet_received
The packet_received event indicates that a QUIC packet was received.
It has Core importance level.
Marx, et al. Expires 6 May 2027 [Page 22]
Internet-Draft QUIC event definitions for qlog November 2026
QUICPacketReceived = {
header: PacketHeader
? frames: [* $QuicFrame]
; only if header.packet_type === "stateless_reset"
? stateless_reset_token: StatelessResetToken
; only if header.packet_type === "version_negotiation"
? supported_versions: [+ QuicVersion]
? raw: RawInfo
? datagram_payload_checksum: uint32
? trigger:
; if packet was buffered because it couldn't be
; decrypted before
"keys_available"
* $$quic-packetreceived-extension
}
Figure 15: QUICPacketReceived definition
The encryption level and packet number space are not logged
explicitly, because header.packet_type implies them for the packet
types that have them.
The datagram_payload_checksum field is described in Section 9.
5.7. packet_dropped
The packet_dropped event indicates that a QUIC packet was dropped.
It has Base importance level.
Marx, et al. Expires 6 May 2027 [Page 23]
Internet-Draft QUIC event definitions for qlog November 2026
QUICPacketDropped = {
; Primarily packet_type should be filled here,
; as other fields might not be decryptable or parsable
? header: PacketHeader
? raw: RawInfo
? datagram_payload_checksum: uint32
? details: {* text => any}
? trigger:
"internal_error" /
"rejected" /
"unsupported" /
"invalid" /
"duplicate" /
"connection_unknown" /
"decryption_failure" /
"keys_unavailable" /
"general"
* $$quic-packetdropped-extension
}
Figure 16: QUICPacketDropped definition
The trigger field gives a general reason for dropping the packet, and
the details field can hold additional implementation-specific
information. Some example situations for each trigger value include:
* "internal_error": not initialized, out of memory
* "rejected": limits reached, DDoS protection, unwilling to track
more paths
* "unsupported": unknown or unsupported version
* "invalid": packet parsing or validation error
* "duplicate": duplicate packet
* "connection_unknown": packet does not relate to a known connection
or connection ID
* "decryption_failure": decryption failed
* "keys_unavailable": decryption keys were unavailable
* "general": situations not clearly covered in the other categories
Marx, et al. Expires 6 May 2027 [Page 24]
Internet-Draft QUIC event definitions for qlog November 2026
Packets dropped as "unsupported" or "connection_unknown" often cannot
be tied to a connection; see Section 1.3.
The datagram_payload_checksum field is described in Section 9.
5.8. packet_buffered
The packet_buffered event is emitted when a packet is buffered
because it cannot be processed yet, for example because the keys to
decrypt it are not yet available. Its full contents can be logged
later, in a packet_received event, once it is processed. It has Base
importance level.
QUICPacketBuffered = {
; primarily packet_type should be filled here as other elements
; might not be available yet
? header: PacketHeader
? raw: RawInfo
? datagram_payload_checksum: uint32
? trigger:
; indicates the parser cannot keep up, temporarily buffers
; packet for later processing
"backpressure" /
; if packet cannot be decrypted because the proper keys were
; not yet available
"keys_unavailable"
* $$quic-packetbuffered-extension
}
Figure 17: QUICPacketBuffered definition
The datagram_payload_checksum field is described in Section 9.
5.9. packets_acked
The packets_acked event is emitted when one or more sent packets are
acknowledged by the peer for the first time. It has Extra importance
level.
Successive ACK frames can acknowledge the same packet, but this event
is emitted only for the first acknowledgment of each packet. This
information can also be deduced from received ACK frames, though
finding the first acknowledgment needs extra processing.
Implementations that do not log frame contents can use this event
instead.
Marx, et al. Expires 6 May 2027 [Page 25]
Internet-Draft QUIC event definitions for qlog November 2026
QUICPacketsAcked = {
? packet_number_space: $PacketNumberSpace
? packet_numbers: [+ uint64]
* $$quic-packetsacked-extension
}
Figure 18: QUICPacketsAcked definition
The packet_number_space field defaults to "application_data", the
packet number space that most packets in a typical QUIC connection
use.
5.10. udp_datagrams_sent
The udp_datagrams_sent event indicates that one or more UDP datagrams
were passed to the network socket. It can show how QUIC packet
buffers are drained to the operating system. It has Extra importance
level.
QUICUDPDatagramsSent = {
; to support passing multiple at once
? count: uint16
; The RawInfo fields do not include the UDP headers,
; only the UDP payload
? raw: [+ RawInfo]
; ECN bits in the IP header
? ecn: [+ ECN]
? datagram_payload_checksums: [+ uint32]
* $$quic-udpdatagramssent-extension
}
Figure 19: QUICUDPDatagramsSent definition
The RawInfo fields exclude UDP headers, because QUIC implementations
do not always handle UDP directly.
If an event omits the ecn field, the ECN bits are the same as on the
last udp_datagrams_sent event.
The datagram_payload_checksums field is described in Section 9.
Marx, et al. Expires 6 May 2027 [Page 26]
Internet-Draft QUIC event definitions for qlog November 2026
5.11. udp_datagrams_received
The udp_datagrams_received event indicates that one or more UDP
datagrams were received from the network socket. It can show how the
operating system passes datagrams to the user-space stack. It has
Extra importance level.
QUICUDPDatagramsReceived = {
; to support passing multiple at once
? count: uint16
; The RawInfo fields do not include the UDP headers,
; only the UDP payload
? raw: [+ RawInfo]
; ECN bits in the IP header
? ecn: [+ ECN]
? datagram_payload_checksums: [+ uint32]
* $$quic-udpdatagramsreceived-extension
}
Figure 20: QUICUDPDatagramsReceived definition
If an event omits the ecn field, the ECN bits are the same as on the
last udp_datagrams_received event.
The datagram_payload_checksums field is described in Section 9.
5.12. udp_datagram_dropped
The udp_datagram_dropped event indicates that a UDP datagram was
dropped, typically because it does not contain a valid QUIC packet.
If the datagram contains a valid QUIC packet that is dropped for
another reason, the packet_dropped event (Section 5.7) is used
instead. It has Extra importance level.
QUICUDPDatagramDropped = {
; The RawInfo fields do not include the UDP headers,
; only the UDP payload
? raw: RawInfo
* $$quic-udpdatagramdropped-extension
}
Marx, et al. Expires 6 May 2027 [Page 27]
Internet-Draft QUIC event definitions for qlog November 2026
Figure 21: QUICUDPDatagramDropped definition
5.13. stream_state_updated
The stream_state_updated event is emitted when the state of a QUIC
stream changes; see Section 3 of [QUIC-TRANSPORT]. Most state
changes can be inferred from the frames that are sent and received,
but an explicit event can be easier to use. It has Base importance
level.
QUIC stream IDs encode whether a stream is unidirectional or
bidirectional (see Section 2.1 of [QUIC-TRANSPORT]), but the optional
stream_type field states it directly.
Section 3 of [QUIC-TRANSPORT] describes the sending and receiving
parts of a stream, each with its own state machine. The stream_side
field says which part's state changed. If both parts change state at
the same time, for example when both become "closed", two events with
different stream_side values SHOULD be logged.
Marx, et al. Expires 6 May 2027 [Page 28]
Internet-Draft QUIC event definitions for qlog November 2026
StreamType = "unidirectional" /
"bidirectional"
QUICStreamStateUpdated = {
stream_id: uint64
? stream_type: StreamType
? old: $StreamState
new: $StreamState
stream_side: "sending" /
"receiving"
? trigger:
; stream state change was initiated by a local action
"local" /
; stream state change was initiated by a remote action
"remote"
* $$quic-streamstateupdated-extension
}
BaseStreamStates = "idle" /
"open" /
"closed"
GranularStreamStates =
; bidirectional stream states, RFC 9000 Section 3.4.
"half_closed_local" /
"half_closed_remote" /
; sending-side stream states, RFC 9000 Section 3.1.
"ready" /
"send" /
"data_sent" /
"reset_sent" /
; receive-side stream states, RFC 9000 Section 3.2.
"receive" /
"size_known" /
"data_read" /
"reset_read" /
; both-side states
"data_received" /
"reset_received" /
; qlog-defined: memory actually freed
"destroyed"
$StreamState /= BaseStreamStates / GranularStreamStates
Figure 22: QUICStreamStateUpdated definition
Marx, et al. Expires 6 May 2027 [Page 29]
Internet-Draft QUIC event definitions for qlog November 2026
QUIC implementations SHOULD log the BaseStreamStates, and can add the
GranularStreamStates when more in-depth debugging is required. Tools
SHOULD handle both kinds equally.
The trigger field can show which endpoint initiated a state change,
for example when a stream is closed because of a RESET_STREAM or
STOP_SENDING frame.
5.14. Frame-Related Events
While the packet_sent (Section 5.5) and packet_received (Section 5.6)
events can convey all frames contained in a single QUIC packet, some
implementations might not be able or willing to include frame
information at the moment either event is logged.
The frames_created and frames_parsed events log frames independently
of packets.
A qlog trace can contain both packet- and frame-related events.
However, it is RECOMMENDED that implementations avoid generating
events with duplicate or redundant frame information, since doing so
inflates the size of logs.
Where an implementation logs both packet- and frame-related events,
the optional packet_numbers field in frame-related events can be used
to link frames to packets explicitly. The field is an array so that
a single event can log frames that belong to different packets. The
frames and packet_numbers arrays are mapped to each other by the
position and order of their entries. If the packet_numbers field is
logged, every frame MUST have a corresponding packet number at the
same index.
For example, an instance of the frames_parsed event that represents
four STREAM frames received over two packets can be serialized as:
"frames":[
{"frame_type":"stream","stream_id":0,"offset":0,"raw":{"length":5}},
{"frame_type":"stream","stream_id":0,"offset":5,"raw":{"length":5}},
{"frame_type":"stream","stream_id":1,"offset":0,"raw":{"length":9}},
{"frame_type":"stream","stream_id":1,"offset":9,"raw":{"length":9}}
],
"packet_numbers":[
1,
1,
2,
2
]
Marx, et al. Expires 6 May 2027 [Page 30]
Internet-Draft QUIC event definitions for qlog November 2026
Frame-related events omit information that is available in the
packet_received or packet_sent event, such as the packet's encryption
level. Use cases that need such information are better served by
those events.
Extensions can use frame-related events to log information that is
not available when a packet event is logged, for example because
frame processing was deferred.
5.14.1. frames_created
The frames_created event indicates that a set of QUIC frames was
created. It has Extra importance level.
QUICFramesCreated = {
frames: [* $QuicFrame]
? packet_numbers: [* uint64]
* $$quic-framescreated-extension
}
Figure 23: QUICFramesCreated definition
5.14.2. frames_parsed
The frames_parsed event indicates that a set of QUIC frames was
parsed. It has Extra importance level.
QUICFramesParsed = {
frames: [* $QuicFrame]
? packet_numbers: [* uint64]
* $$quic-framesparsed-extension
}
Figure 24: QUICFramesParsed definition
5.15. stream_data_moved
The stream_data_moved event indicates that QUIC stream data moved
between layers. It has Base importance level.
For example, data can move from an application protocol such as
HTTP/3 to QUIC stream buffers, or the other way. Logging these moves
can show the flow of data, how long data stays in each buffer, and
the overhead introduced by each layer.
Marx, et al. Expires 6 May 2027 [Page 31]
Internet-Draft QUIC event definitions for qlog November 2026
This event can also show whether received stream data is passed to
the application protocol immediately or in batches. Data can be
passed, for example, once per received packet, or in a batch after
all received packets are processed. This can help identify
bottlenecks, flow control issues, or scheduling problems.
The raw.length field gives the number of bytes moved. Because this
event covers stream data only, there are no packet or frame headers,
and raw.length MUST reflect that.
The additional_info field can log information about the stream state.
For example, an application that moves data into the transport and
ends the stream at the same time can log "fin_set". A transport that
has received an instruction to reset a stream can tell the
application with "stream_reset". In both cases, raw.length can be
omitted or be zero.
This event covers only data in QUIC streams. For data in QUIC
datagrams, see the datagram_data_moved event (Section 5.16).
QUICStreamDataMoved = {
? stream_id: uint64
? offset: uint64
? from: $DataLocation
? to: $DataLocation
? additional_info: $DataMovedAdditionalInfo
? raw: RawInfo
* $$quic-streamdatamoved-extension
}
$DataLocation /= "application" /
"transport" /
"network"
$DataMovedAdditionalInfo /= "fin_set" /
"stream_reset"
Figure 25: QUICStreamDataMoved definition
5.16. datagram_data_moved
The datagram_data_moved event indicates that QUIC datagram data (see
[QUIC-DATAGRAM]) moved between layers. It has Base importance level.
Marx, et al. Expires 6 May 2027 [Page 32]
Internet-Draft QUIC event definitions for qlog November 2026
For example, data can move from an application protocol such as
WebTransport to QUIC buffers, or the other way. Logging these moves
can show the flow of data, how long data stays in each buffer, and
the overhead introduced by each layer.
This event can also show whether received datagram data is passed to
the application protocol immediately or in batches. Data can be
passed, for example, once per received packet, or in a batch after
all received packets are processed. This can help identify
bottlenecks or scheduling problems.
The raw.length field gives the number of bytes moved. Because this
event covers datagram data only, there are no packet or frame
headers, and raw.length MUST reflect that.
This event covers only data in QUIC datagrams. For data in QUIC
streams, see the stream_data_moved event (Section 5.15).
QUICDatagramDataMoved = {
? from: $DataLocation
? to: $DataLocation
? raw: RawInfo
* $$quic-datagramdatamoved-extension
}
Figure 26: QUICDatagramDataMoved definition
5.17. datagram_dropped
The datagram_dropped event indicates that QUIC DATAGRAM data (see
[RFC9221]) was discarded locally, before sending or after reception.
It has Base importance level.
The direction field identifies the sending or receiving side, and
trigger indicates the reason for discarding the data. The raw.length
field MUST count discarded payload bytes, excluding packet and frame
headers.
Received DATAGRAM data can be discarded while its packet is still
acknowledged. For drops of entire QUIC packets, use packet_dropped
(Section 5.7).
Marx, et al. Expires 6 May 2027 [Page 33]
Internet-Draft QUIC event definitions for qlog November 2026
QUICDatagramDropped = {
? direction: "sending" /
"receiving"
? raw: RawInfo
? trigger:
; insufficient space in a send or receive buffer
"buffer_full" /
; datagram data exceeds the maximum payload size
"too_large" /
text
* $$quic-datagramdropped-extension
}
Figure 27: QUICDatagramDropped definition
5.18. connection_data_blocked_updated
The connection_data_blocked_updated event indicates that the QUIC
connection became blocked or unblocked for sending data. It has
Extra importance level.
Depending on the reason, a blocked connection cannot send stream
data, datagram data, or both, until that reason is resolved. The
stream_data_blocked_updated and datagram_data_blocked_updated events
give more detail for each type of data.
QUICConnectionDataBlockedUpdated = {
? old: $BlockedState
new: $BlockedState
? reason: $BlockedReason
* $$quic-connectiondatablockedupdated-extension
}
$BlockedState /= "blocked" /
"unblocked"
$BlockedReason /= "scheduling" /
"pacing" /
"amplification_protection" /
"congestion_control" /
"connection_flow_control" /
"stream_flow_control" /
"stream_id" /
"application"
Marx, et al. Expires 6 May 2027 [Page 34]
Internet-Draft QUIC event definitions for qlog November 2026
Figure 28: QUICConnectionDataBlockedUpdated definition
5.19. stream_data_blocked_updated
The stream_data_blocked_updated event indicates that a QUIC stream
became blocked or unblocked for sending. It has Extra importance
level.
QUICStreamDataBlockedUpdated = {
? old: $BlockedState
new: $BlockedState
stream_id: uint64
? reason: $BlockedReason
* $$quic-streamdatablockedupdated-extension
}
Figure 29: QUICStreamDataBlockedUpdated definition
5.20. datagram_data_blocked_updated
The datagram_data_blocked_updated event indicates that QUIC datagrams
became blocked or unblocked for sending. It has Extra importance
level.
QUICDatagramDataBlockedUpdated = {
? old: $BlockedState
new: $BlockedState
? reason: $BlockedReason
* $$quic-datagramdatablockedupdated-extension
}
Figure 30: QUICDatagramDataBlockedUpdated definition
5.21. migration_state_updated
The migration_state_updated event logs the progress of a connection
migration by a client; see Section 9 of [QUIC-TRANSPORT]. It has
Extra importance level.
Most details of a migration can be inferred from PATH_CHALLENGE and
PATH_RESPONSE frames, together with tuple_assigned events. However,
it can be useful to log the progress of the migration, and any
decisions made, in a single event.
Marx, et al. Expires 6 May 2027 [Page 35]
Internet-Draft QUIC event definitions for qlog November 2026
The MigrationState values follow the steps in Section 9 of
[QUIC-TRANSPORT]: the probing_* values cover probing a new path
(Section 9.1 of [QUIC-TRANSPORT]), and the migration_* values cover
migrating the connection (Section 9.2 of [QUIC-TRANSPORT]).
Implementations that log per-path information in
migration_state_updated events SHOULD also emit tuple_assigned
events, to serve as the ground truth for tuple information.
QUICMigrationStateUpdated = {
? old: MigrationState
new: MigrationState
? tuple_id: TupleID
; the information for traffic going towards the remote receiver
? tuple_remote: TupleEndpointInfo
; the information for traffic coming in at the local endpoint
? tuple_local: TupleEndpointInfo
* $$quic-migrationstateupdated-extension
}
; Note that MigrationState does not describe a full state machine
; These entries are not necessarily chronological,
; nor will they always all appear during
; a connection migration attempt.
MigrationState =
; probing packets are sent, migration not initiated yet
"probing_started" /
; did not get reply to probing packets,
; discarding path as an option
"probing_abandoned" /
; received reply to probing packets, path is migration candidate
"probing_successful" /
; non-probing packets are sent, attempting migration
"migration_started" /
; something went wrong during the migration, abandoning attempt
"migration_abandoned" /
; new path is now fully used, old path is discarded
"migration_complete"
Figure 31: QUICMigrationStateUpdated definition
Marx, et al. Expires 6 May 2027 [Page 36]
Internet-Draft QUIC event definitions for qlog November 2026
5.22. timer_updated
The timer_updated event is emitted when a timer changes state. It
has Extra importance level.
The event_type field takes one of three values:
* "set": the timer is set, and delta gives the time until it
triggers
* "expired": the timer expired
* "cancelled": the timer was cancelled
An update to an active timer's timeout is logged as a new "set"
event.
The recovery timer types correspond to timers in Section 6 of
[QUIC-RECOVERY] and Appendix A.8 of [QUIC-RECOVERY]:
* "ack": the time threshold loss detection timeout
* "pto": the probe timeout
* "loss_timeout": the single, multi-modal loss detection timer that
covers both
QUIC uses a variety of timers, and how they are used can depend on
the implementation. Implementers can add fields to this event
through $$quic-timerupdated-extension, or add timer types through
$TimerType.
Marx, et al. Expires 6 May 2027 [Page 37]
Internet-Draft QUIC event definitions for qlog November 2026
; a non-exhaustive list of typically employed timers
$TimerType /= "ack" /
"pto" /
"loss_timeout" /
"path_validation" /
"handshake_timeout" /
"idle_timeout"
QUICTimerUpdated = {
? timer_type: $TimerType
; to disambiguate in case there are multiple timers
; of the same type
? timer_id: uint64
; if used for recovery timers, this can be useful information
? packet_number_space: $PacketNumberSpace
event_type: "set" /
"expired" /
"cancelled"
; if event_type === "set": delta time is in ms from
; this event's timestamp until when the timer should trigger
? delta: float32
* $$quic-timerupdated-extension
}
Figure 32: QUICTimerUpdated definition
6. Security Events
6.1. key_updated
The key_updated event indicates that a key was installed or updated.
It has Base importance level.
This happens when TLS provides new keys during the handshake, and at
each 1-RTT key update; see Section 6 of [QUIC-TLS].
Marx, et al. Expires 6 May 2027 [Page 38]
Internet-Draft QUIC event definitions for qlog November 2026
QUICKeyUpdated = {
key_type: $KeyType
? old: hexstring
? new: hexstring
; needed for 1RTT key updates
? key_phase: uint64
? trigger:
; (e.g., initial, handshake and 0-RTT keys
; are generated by TLS)
"tls" /
"remote_update" /
"local_update"
* $$quic-keyupdated-extension
}
Figure 33: QUICKeyUpdated definition
The key_phase field holds the full key phase, which identifies the
generation of keys; it corresponds to @M and @N in Figure 9 of
Section 6 of [QUIC-TLS]. The Key Phase bit in the packet header is
the least significant bit of this value.
6.2. key_discarded
The key_discarded event indicates that a key was discarded. It has
Base importance level.
Keys are discarded, for example, when the connection moves to a new
encryption level during the handshake, or after a key update; see
Section 4.9 of [QUIC-TLS].
QUICKeyDiscarded = {
key_type: $KeyType
? key: hexstring
; needed for 1RTT key updates
? key_phase: uint64
? trigger:
; (e.g., initial, handshake and 0-RTT keys
; are generated by TLS)
"tls" /
"remote_update" /
"local_update"
* $$quic-keydiscarded-extension
}
Marx, et al. Expires 6 May 2027 [Page 39]
Internet-Draft QUIC event definitions for qlog November 2026
Figure 34: QUICKeyDiscarded definition
7. Recovery Events
Most of the events in this section are kept generic to support
different recovery approaches and congestion control algorithms. The
old, new, and trigger fields of congestion_state_updated, for
instance, are free text, so their values depend on the algorithm.
Tools that process these events SHOULD try to handle such values even
when they don't recognize them. For example, a tool that plots
congestion states on a timeline can label an unknown state with the
value of the new field.
7.1. recovery_parameters_set
The recovery_parameters_set event groups initial parameters from both
loss detection and congestion control into a single event. It has
Base importance level.
These parameters are typically set once and never change.
Implementations that change them during the connection MAY emit the
recovery_parameters_set event more than once.
The reordering_threshold field contains the packet threshold for loss
detection, or "disabled" if packet-threshold loss detection is
disabled.
Marx, et al. Expires 6 May 2027 [Page 40]
Internet-Draft QUIC event definitions for qlog November 2026
QUICRecoveryParametersSet = {
; Loss detection, see RFC 9002 Appendix A.2
; in amount of packets
? reordering_threshold: uint16 / "disabled"
; as RTT multiplier
? time_threshold: float32
; in ms
timer_granularity: uint16
; in ms
? initial_rtt:float32
; congestion control, see RFC 9002 Appendix B.2
; in bytes. Note that this could be updated after pmtud
? max_datagram_size: uint32
; in bytes
? initial_congestion_window: uint64
; Note that this could change when max_datagram_size changes
; in bytes
? minimum_congestion_window: uint64
? loss_reduction_factor: float32
; as PTO multiplier
? persistent_congestion_threshold: uint16
* $$quic-recoveryparametersset-extension
}
Figure 35: QUICRecoveryParametersSet definition
Parameters that this document does not define, such as those of other
loss detection and recovery algorithms, can be added through $$quic-
recoveryparametersset-extension.
7.2. recovery_metrics_updated
The recovery_metrics_updated event is emitted when one or more of the
observable recovery metrics change value. It has Core importance
level.
Marx, et al. Expires 6 May 2027 [Page 41]
Internet-Draft QUIC event definitions for qlog November 2026
Implementations SHOULD group all metric updates that happen at or
around the same time into a single recovery_metrics_updated event.
For example, if min_rtt and smoothed_rtt change at the same time,
they are logged in one event, not two. Each event is only guaranteed
to contain at least one of the listed metrics.
QUICRecoveryMetricsUpdated = {
; Loss detection, see RFC 9002 Appendix A.3
; all following rtt fields are expressed in ms
? min_rtt: float32
? smoothed_rtt: float32
? latest_rtt: float32
? rtt_variance: float32
? pto_count: uint16
; Congestion control, see RFC 9002 Appendix B.2.
; in bytes
? congestion_window: uint64
? bytes_in_flight: uint64
; in bytes
? ssthresh: uint64
; qlog defined
; sum of all packet number spaces
? packets_in_flight: uint64
; in bits per second
? pacing_rate: uint64
* $$quic-recoverymetricsupdated-extension
}
Figure 36: QUICRecoveryMetricsUpdated definition
To make logging easier, implementations MAY log values that are the
same as previously reported values; for example, two consecutive
recovery_metrics_updated events can report the same min_rtt.
However, implementations SHOULD try to log only values that changed.
Metrics that this document does not define, such as those of other
loss detection and recovery algorithms, can be added through $$quic-
recoverymetricsupdated-extension.
Marx, et al. Expires 6 May 2027 [Page 42]
Internet-Draft QUIC event definitions for qlog November 2026
7.3. congestion_state_updated
The congestion_state_updated event indicates when the congestion
controller enters a new state that changes its behavior. It has Base
importance level.
This document does not define values for the event's fields.
Congestion control algorithms have different states and different
causes for moving between them, and stacks can implement the same
algorithm differently. For example, the NewReno controller in
Section 7.3 of [QUIC-RECOVERY] has three states: slow start,
recovery, and congestion avoidance.
QUICCongestionStateUpdated = {
? old: text
new: text
? trigger: text
* $$quic-congestionstateupdated-extension
}
Figure 37: QUICCongestionStateUpdated definition
The trigger field SHOULD be logged if a state change can have more
than one cause. For example, NewReno enters recovery when it detects
packet loss or when the ECN-CE count increases, so the trigger field
shows which of the two caused the change.
7.4. packet_lost
The packet_lost event is emitted when loss detection declares a
packet lost. It has Core importance level.
QUICPacketLost = {
; should include at least the packet_type and packet_number
? header: PacketHeader
? frames: [* $QuicFrame]
? is_mtu_probe_packet: bool
? trigger:
"reordering_threshold" /
"time_threshold" /
"pto_expired"
* $$quic-packetlost-extension
}
Marx, et al. Expires 6 May 2027 [Page 43]
Internet-Draft QUIC event definitions for qlog November 2026
Figure 38: QUICPacketLost definition
The frames field lists the frames that the lost packet carried. It
is optional, because not all implementations keep sent packets in
full. The data that is then marked for retransmission can be logged
with the marked_for_retransmit event (Section 7.5).
The is_mtu_probe_packet field marks a packet that was sent as a Path
MTU probe. The loss of such a packet is not a reliable sign of
congestion; see Section 14.4 of [QUIC-TRANSPORT]. It defaults to
false.
The trigger field SHOULD be logged. Its value shows how loss
detection declared the packet lost:
* reordering_threshold: the packet threshold was exceeded; see
Section 6.1.1 of [QUIC-RECOVERY].
* time_threshold: the time threshold was exceeded; see Section 6.1.2
of [QUIC-RECOVERY].
* pto_expired: the probe timeout expired, and the sender declared
the packet lost instead of sending a probe; see Section 6.2.4 of
[QUIC-RECOVERY].
7.5. marked_for_retransmit
The marked_for_retransmit event indicates which data was marked for
retransmission after packet loss was detected. It has Extra
importance level.
This single event covers all types of retransmittable data, which it
logs using the existing QUIC frame definitions.
A packet_lost event (Section 7.4) records that a packet was declared
lost, and can list the frames it carried. A marked_for_retransmit
event records what the implementation then marks for retransmission.
The two can differ, because not every frame is retransmitted (ACK and
PADDING frames never are), and retransmitted data need not be sent in
the same frames; see Section 13.3 of [QUIC-TRANSPORT].
An implementation that retransmits the frames of a lost packet
unchanged can log them here, or skip this event and use the frames in
the packet_lost event instead. An implementation with more complex
logic, such as one that marks ranges of a stream's send buffer as in
flight, or one that does not keep sent frames in full, can log frames
that describe the data it marked for retransmission. These frames
need not match any frame that was sent or will be sent.
Marx, et al. Expires 6 May 2027 [Page 44]
Internet-Draft QUIC event definitions for qlog November 2026
If an implementation logs packet_sent events, tools can infer much of
this data from them. For example, overlapping stream offsets and
lengths show when data was retransmitted.
QUICMarkedForRetransmit = {
frames: [+ $QuicFrame]
* $$quic-markedforretransmit-extension
}
Figure 39: QUICMarkedForRetransmit definition
7.6. ecn_state_updated
The ecn_state_updated event indicates a progression in the ECN state
machine as described in Appendix A.4 of [QUIC-TRANSPORT]. It has
Extra importance level.
QUICECNStateUpdated = {
? old: ECNState
new: ECNState
? trigger: text
* $$quic-ecnstateupdated-extension
}
ECNState =
; ECN testing in progress
"testing" /
; ECN state unknown, waiting for acknowledgements
; for testing packets
"unknown" /
; ECN testing failed
"failed" /
; testing was successful
"capable"
Figure 40: QUICECNStateUpdated definition
The trigger field can be used to log why the state changed, for
example which ECN validation check in Section 13.4.2 of
[QUIC-TRANSPORT] failed.
8. QUIC Data Type Definitions
8.1. QuicVersion
QuicVersion = hexstring
Marx, et al. Expires 6 May 2027 [Page 45]
Internet-Draft QUIC event definitions for qlog November 2026
Figure 41: QuicVersion definition
8.2. ConnectionID
ConnectionID = hexstring
Figure 42: ConnectionID definition
8.3. Initiator
Initiator = "local" /
"remote"
Figure 43: Initiator definition
8.4. IPAddressPort
; an IP address can either be a "human readable" form
; (e.g., "127.0.0.1" for v4 or
; "2001:0db8:85a3:0000:0000:8a2e:0370:7334" for v6) or
; use a raw byte-form (as the string forms can be ambiguous).
; Additionally, the IP address and port pair can be logged as an
; application-defined redacted string for privacy or security reasons.
IPAddressPort = {
ip: text / hexstring
port: uint16
} / text
Figure 44: IPAddressPort definition
8.5. TupleEndpointInfo
TupleEndpointInfo describes one half, or direction, of a four-tuple.
A full tuple has two halves: the server sends to the client's IP
address and port, and the client sends to the server's IP address and
port. Each direction uses its own destination connection ID.
Structures that log tuple information SHOULD therefore include two
TupleEndpointInfo instances, one for each half of the tuple.
Marx, et al. Expires 6 May 2027 [Page 46]
Internet-Draft QUIC event definitions for qlog November 2026
TupleEndpointInfo = {
? address_v4: IPAddressPort
? address_v6: IPAddressPort
; Even though usually only a single ConnectionID
; is associated with a given tuple/path at a time,
; there are situations where there can be an overlap
; or a need to keep track of previous ConnectionIDs
? connection_ids: [+ ConnectionID]
* $$quic-tupleendpointinfo-extension
}
Figure 45: TupleEndpointInfo definition
8.6. PacketType
$PacketType /= "initial" /
"handshake" /
"0RTT" /
"1RTT" /
"retry" /
"version_negotiation" /
"stateless_reset" /
"unknown"
Figure 46: PacketType definition
8.7. PacketNumberSpace
$PacketNumberSpace /= "initial" /
"handshake" /
"application_data"
Figure 47: PacketNumberSpace definition
8.8. PacketHeader
If a packet type has no known $PacketType string, packet_type can be
"unknown", and packet_type_bytes then holds the numerical value
without variable-length integer encoding.
PacketHeader omits the fixed bit and the reserved bits because QUIC
version 1 gives them fixed values; see Section 17 of
[QUIC-TRANSPORT]. Their values can be logged in the raw.data field
of the event that logs the PacketHeader.
Marx, et al. Expires 6 May 2027 [Page 47]
Internet-Draft QUIC event definitions for qlog November 2026
QUIC extensions that use these bits, such as the QUIC Bit greasing
extension ([GREASEBIT]), can log that use with new events, similar to
spin_bit_updated, or with fields added to PacketHeader through
$$quic-packetheader-extension.
For long header packets of type initial, handshake, and 0RTT, the
length field of the packet header is logged in the qlog raw.length
field, and the value signifies the length of the packet number plus
the payload.
PacketHeader = {
packet_type: $PacketType
; only if packet_type === "unknown"
? packet_type_bytes: uint64
; only if packet_type === "1RTT"
? spin_bit: bool
; only if packet_type === "1RTT", and if the key phase was
; determined from the key_phase_bit
? key_phase: uint64
; only if packet_type === "1RTT", and if key_phase is not set
? key_phase_bit: bool
; only if packet_type === "initial" || "handshake" || "0RTT" ||
; "1RTT"
? packet_number_length: uint8
; only if packet_type === "initial" || "handshake" || "0RTT" ||
; "1RTT"
? packet_number: uint64
; only if packet_type === "initial" || "retry"
? token: Token
; only if present in the header.
; if correctly using connection_id_updated events,
; dcid can be skipped for 1RTT packets
? version: QuicVersion
? scil: uint8
? dcil: uint8
? scid: ConnectionID
? dcid: ConnectionID
* $$quic-packetheader-extension
}
Marx, et al. Expires 6 May 2027 [Page 48]
Internet-Draft QUIC event definitions for qlog November 2026
Figure 48: PacketHeader definition
8.9. Token
Token = {
? type: $TokenType
; decoded fields included in the token
; (typically: peer's IP address, creation time)
? details: {
* text => any
}
? raw: RawInfo
* $$quic-token-extension
}
$TokenType /= "retry" /
"resumption"
Figure 49: Token definition
The token carried in an Initial packet is either a token from a Retry
packet, or one that the server provided earlier in a NEW_TOKEN frame,
for address validation in a later connection; see Section 8.1.3 of
[QUIC-TRANSPORT]. Both kinds typically encode metadata that the
server uses to check the token, but the metadata and its format are
implementation-specific. The details field can log that metadata.
8.10. StatelessResetToken
; always 16 bytes
StatelessResetToken = hexstring
Figure 50: StatelessResetToken definition
The stateless reset token is defined in Section 10.3 of
[QUIC-TRANSPORT].
8.11. KeyType
Marx, et al. Expires 6 May 2027 [Page 49]
Internet-Draft QUIC event definitions for qlog November 2026
$KeyType /= "server_initial_secret" /
"client_initial_secret" /
"server_handshake_secret" /
"client_handshake_secret" /
"server_0rtt_secret" /
"client_0rtt_secret" /
"server_1rtt_secret" /
"client_1rtt_secret"
Figure 51: KeyType definition
8.12. ECN
ECN holds the ECN codepoint carried in the IP header; see
Section 13.4 of [QUIC-TRANSPORT].
ECN = "Not-ECT" / "ECT(1)" / "ECT(0)" / "CE"
Figure 52: ECN definition
8.13. QUIC Frames
The generic $QuicFrame is defined here as a CDDL "type socket"
extension point. It can be extended to support additional QUIC frame
types.
; The QuicFrame is any key-value map (e.g., JSON object)
$QuicFrame /= {
* text => any
}
Figure 53: QuicFrame type socket definition
The QUIC frame types defined in this document are as follows:
Marx, et al. Expires 6 May 2027 [Page 50]
Internet-Draft QUIC event definitions for qlog November 2026
QuicBaseFrames = PaddingFrame /
PingFrame /
AckFrame /
ResetStreamFrame /
ResetStreamAtFrame /
StopSendingFrame /
CryptoFrame /
NewTokenFrame /
StreamFrame /
MaxDataFrame /
MaxStreamDataFrame /
MaxStreamsFrame /
DataBlockedFrame /
StreamDataBlockedFrame /
StreamsBlockedFrame /
NewConnectionIDFrame /
RetireConnectionIDFrame /
PathChallengeFrame /
PathResponseFrame /
ConnectionCloseFrame /
HandshakeDoneFrame /
UnknownFrame /
DatagramFrame
$QuicFrame /= QuicBaseFrames
Figure 54: QuicBaseFrames definition
8.13.1. PaddingFrame
A PADDING frame is a single byte with the value 0, so each padding
byte is its own frame; see Section 19.1 of [QUIC-TRANSPORT]. Logging
each one as a separate PaddingFrame could add hundreds of entries to
a single packet event, for example when a client pads an Initial
packet to 1200 bytes. Implementations SHOULD instead log a single
PaddingFrame for the packet, and set its raw.payload_length field to
the number of PADDING frames in the packet.
PaddingFrame = {
frame_type: "padding"
? raw: RawInfo
}
Figure 55: PaddingFrame definition
8.13.2. PingFrame
Marx, et al. Expires 6 May 2027 [Page 51]
Internet-Draft QUIC event definitions for qlog November 2026
PingFrame = {
frame_type: "ping"
? raw: RawInfo
}
Figure 56: PingFrame definition
8.13.3. AckFrame
; either a single number (e.g., [1]) or two numbers (e.g., [1,2]).
; For two numbers:
; the first number is "from": lowest packet number in interval
; the second number is "to": up to and including the highest
; packet number in the interval
AckRange = [1*2 uint64]
AckFrame = {
frame_type: "ack"
; in ms
? ack_delay: float32
; e.g., looks like [[1,2],[4,5], [7], [10,22]] serialized
? acked_ranges: [+ AckRange]
; ECN (explicit congestion notification) related fields
; (not always present)
? ect1: uint64
? ect0: uint64
? ce: uint64
? raw: RawInfo
}
Figure 57: AckFrame definition
The ranges in acked_ranges do not have to be in order; for example,
[[5,9],[1,4]] is valid.
The two numbers in a range can be equal; for example, [120,120] means
that packet 120 was acknowledged. In that case, implementations
SHOULD log [120] instead, and tools MUST handle both forms.
8.13.4. ResetStreamFrame
If an error code has no known ApplicationError string, error can be
"unknown", and error_code then holds the numerical value without
variable-length integer encoding.
Marx, et al. Expires 6 May 2027 [Page 52]
Internet-Draft QUIC event definitions for qlog November 2026
ResetStreamFrame = {
frame_type: "reset_stream"
stream_id: uint64
error: $ApplicationError
; if error === "unknown"
? error_code: uint64
; in bytes
final_size: uint64
? raw: RawInfo
}
Figure 58: ResetStreamFrame definition
8.13.5. ResetStreamAtFrame
The RESET_STREAM_AT frame is defined in Section 4 of
[RESET-STREAM-AT].
If an error code has no known ApplicationError string, error can be
"unknown", and error_code then holds the numerical value without
variable-length integer encoding.
ResetStreamAtFrame = {
frame_type: "reset_stream_at"
stream_id: uint64
error: $ApplicationError
; if error === "unknown"
? error_code: uint64
; in bytes
final_size: uint64
; in bytes
reliable_size: uint64
? raw: RawInfo
}
Figure 59: ResetStreamAtFrame definition
8.13.6. StopSendingFrame
If an error code has no known ApplicationError string, error can be
"unknown", and error_code then holds the numerical value without
variable-length integer encoding.
Marx, et al. Expires 6 May 2027 [Page 53]
Internet-Draft QUIC event definitions for qlog November 2026
StopSendingFrame = {
frame_type: "stop_sending"
stream_id: uint64
error: $ApplicationError
; if error === "unknown"
? error_code: uint64
? raw: RawInfo
}
Figure 60: StopSendingFrame definition
8.13.7. CryptoFrame
The length field of the CRYPTO frame MUST be logged in the qlog
raw.length field. The other sub-fields of the raw field are
optional.
CryptoFrame = {
frame_type: "crypto"
offset: uint64
raw: RawInfo
}
Figure 61: CryptoFrame definition
8.13.8. NewTokenFrame
NewTokenFrame = {
frame_type: "new_token"
token: Token
? raw: RawInfo
}
Figure 62: NewTokenFrame definition
8.13.9. StreamFrame
If the STREAM frame contains a length field, it MUST be logged in the
qlog raw.length field. If it does not, the implementation MAY
calculate the actual frame byte length itself and log that in
raw.length if necessary.
The offset field defaults to 0, and the fin field defaults to false.
Marx, et al. Expires 6 May 2027 [Page 54]
Internet-Draft QUIC event definitions for qlog November 2026
StreamFrame = {
frame_type: "stream"
stream_id: uint64
? offset: uint64
? fin: bool
? raw: RawInfo
}
Figure 63: StreamFrame definition
8.13.10. MaxDataFrame
MaxDataFrame = {
frame_type: "max_data"
maximum: uint64
? raw: RawInfo
}
Figure 64: MaxDataFrame definition
8.13.11. MaxStreamDataFrame
MaxStreamDataFrame = {
frame_type: "max_stream_data"
stream_id: uint64
maximum: uint64
? raw: RawInfo
}
Figure 65: MaxStreamDataFrame definition
8.13.12. MaxStreamsFrame
MaxStreamsFrame = {
frame_type: "max_streams"
stream_type: StreamType
maximum: uint64
? raw: RawInfo
}
Figure 66: MaxStreamsFrame definition
8.13.13. DataBlockedFrame
Marx, et al. Expires 6 May 2027 [Page 55]
Internet-Draft QUIC event definitions for qlog November 2026
DataBlockedFrame = {
frame_type: "data_blocked"
limit: uint64
? raw: RawInfo
}
Figure 67: DataBlockedFrame definition
8.13.14. StreamDataBlockedFrame
StreamDataBlockedFrame = {
frame_type: "stream_data_blocked"
stream_id: uint64
limit: uint64
? raw: RawInfo
}
Figure 68: StreamDataBlockedFrame definition
8.13.15. StreamsBlockedFrame
StreamsBlockedFrame = {
frame_type: "streams_blocked"
stream_type: StreamType
limit: uint64
? raw: RawInfo
}
Figure 69: StreamsBlockedFrame definition
8.13.16. NewConnectionIDFrame
NewConnectionIDFrame = {
frame_type: "new_connection_id"
sequence_number: uint64
retire_prior_to: uint64
; mainly used if e.g., for privacy reasons the full
; connection_id cannot be logged
? connection_id_length: uint8
connection_id: ConnectionID
? stateless_reset_token: StatelessResetToken
? raw: RawInfo
}
Figure 70: NewConnectionIDFrame definition
Marx, et al. Expires 6 May 2027 [Page 56]
Internet-Draft QUIC event definitions for qlog November 2026
8.13.17. RetireConnectionIDFrame
RetireConnectionIDFrame = {
frame_type: "retire_connection_id"
sequence_number: uint64
? raw: RawInfo
}
Figure 71: RetireConnectionIDFrame definition
8.13.18. PathChallengeFrame
PathChallengeFrame = {
frame_type: "path_challenge"
; always 8 bytes
? data: hexstring
? raw: RawInfo
}
Figure 72: PathChallengeFrame definition
8.13.19. PathResponseFrame
PathResponseFrame = {
frame_type: "path_response"
; always 8 bytes
? data: hexstring
? raw: RawInfo
}
Figure 73: PathResponseFrame definition
8.13.20. ConnectionCloseFrame
If an error code has no known string, error can be "unknown", and
error_code then holds the numerical value without variable-length
integer encoding.
The trigger_frame_type field logs the Frame Type field, which only
the transport variant of CONNECTION_CLOSE (type 0x1c) carries; see
Section 19.19 of [QUIC-TRANSPORT]. A known frame type is logged as
its frame type string, such as "stream". An unknown frame type is
logged as the numerical value without variable-length integer
encoding.
Marx, et al. Expires 6 May 2027 [Page 57]
Internet-Draft QUIC event definitions for qlog November 2026
The reason phrase in a CONNECTION_CLOSE frame is a byte sequence,
which RFC 9000 recommends be UTF-8; see Section 19.19 of
[QUIC-TRANSPORT]. The reason field holds the reason phrase as text,
and reason_bytes holds the raw bytes, for example when the value is
not UTF-8 or when an endpoint does not want to decode it.
Implementations SHOULD log at least one form and MAY log both.
ErrorSpace = "transport" /
"application"
ConnectionCloseFrame = {
frame_type: "connection_close"
? error_space: ErrorSpace
? error: $TransportError / CryptoError /
$ApplicationError
; if error === "unknown"
? error_code: uint64
? reason: text
? reason_bytes: hexstring
; when error_space === "transport"
? trigger_frame_type: uint64 /
text
? raw: RawInfo
}
Figure 74: ConnectionCloseFrame definition
8.13.21. HandshakeDoneFrame
HandshakeDoneFrame = {
frame_type: "handshake_done"
? raw: RawInfo
}
Figure 75: HandshakeDoneFrame definition
8.13.22. UnknownFrame
The frame_type_bytes field holds the numerical value of the frame
type without variable-length integer encoding.
Marx, et al. Expires 6 May 2027 [Page 58]
Internet-Draft QUIC event definitions for qlog November 2026
UnknownFrame = {
frame_type: "unknown"
frame_type_bytes: uint64
? raw: RawInfo
}
Figure 76: UnknownFrame definition
8.13.23. DatagramFrame
The QUIC DATAGRAM frame is defined in Section 4 of [QUIC-DATAGRAM].
If the DATAGRAM frame contains a length field, it MUST be logged in
the qlog raw.length field. If it does not, the implementation MAY
calculate the actual datagram byte length itself and log that in
raw.length if necessary.
DatagramFrame = {
frame_type: "datagram"
? raw: RawInfo
}
Figure 77: DatagramFrame definition
8.14. TransportError
The generic $TransportError is defined here as a CDDL "type socket"
extension point. It can be extended to support additional transport
errors.
Marx, et al. Expires 6 May 2027 [Page 59]
Internet-Draft QUIC event definitions for qlog November 2026
$TransportError /= "no_error" /
"internal_error" /
"connection_refused" /
"flow_control_error" /
"stream_limit_error" /
"stream_state_error" /
"final_size_error" /
"frame_encoding_error" /
"transport_parameter_error" /
"connection_id_limit_error" /
"protocol_violation" /
"invalid_token" /
"application_error" /
"crypto_buffer_exceeded" /
"key_update_error" /
"aead_limit_reached" /
"no_viable_path" /
"unknown"
; there is no value to reflect CRYPTO_ERROR
; use the CryptoError type instead
Figure 78: TransportError definition
8.15. ApplicationError
Application errors are defined by the application protocol that runs
on top of QUIC, such as HTTP/3, so this document cannot list them.
$ApplicationError is instead defined as a CDDL "type socket"
extension point, with a single "unknown" value.
$ApplicationError /= "unknown"
Figure 79: ApplicationError definition
Event schemas for application protocols MUST add their error strings
by extending the $ApplicationError socket; see Section 8.2 of
[QLOG-MAIN].
8.16. CryptoError
RFC 9001 converts a TLS alert into a QUIC error code by adding the
alert's AlertDescription value to 0x0100; see Section 4.8 of
[QUIC-TLS].
Marx, et al. Expires 6 May 2027 [Page 60]
Internet-Draft QUIC event definitions for qlog November 2026
A fixed list of strings does not fit this range well, so a
CryptoError value is crypto_error_ followed by the resulting QUIC
error code in lowercase hexadecimal, from crypto_error_0x100 to
crypto_error_0x1ff. For example, a handshake_failure alert, which is
0x0128 in QUIC, is logged as crypto_error_0x128.
; all strings from "crypto_error_0x100" to "crypto_error_0x1ff"
CryptoError = text .regexp "crypto_error_0x1[0-9a-f][0-9a-f]"
Figure 80: CryptoError definition
9. Handling Packet Coalescing
Multiple QUIC packets can be coalesced into a single UDP datagram,
especially during the handshake; see Section 12.2 of
[QUIC-TRANSPORT]. Neither QUIC nor UDP provides a way to tell which
packets shared a datagram.
To let tools match QUIC packet events to UDP datagram events, the
optional datagram_payload_checksum field carries a 32-bit CRC32c of
the UDP payload, calculated as described in Section 11.3 of
[RFC9868]. The UDP datagram events carry one checksum per datagram,
in their datagram_payload_checksums field.
10. Security and Privacy Considerations
The security and privacy considerations discussed in Section 14 of
[QLOG-MAIN] apply to this document as well.
11. IANA Considerations
This document registers a new entry in the "qlog event schema URIs"
registry, which was created in Section 15 of [QLOG-MAIN]:
Event schema URI: urn:ietf:params:qlog:events:quic
Namespace: quic
Event Types: server_listening, connection_started,
connection_closed, connection_id_updated, spin_bit_updated,
connection_state_updated, tuple_assigned, mtu_updated,
version_information, alpn_information, parameters_set,
parameters_restored, packet_sent, packet_received, packet_dropped,
packet_buffered, packets_acked, udp_datagrams_sent,
udp_datagrams_received, udp_datagram_dropped,
stream_state_updated, frames_created, frames_parsed,
stream_data_moved, datagram_data_moved, datagram_dropped,
connection_data_blocked_updated, stream_data_blocked_updated,
Marx, et al. Expires 6 May 2027 [Page 61]
Internet-Draft QUIC event definitions for qlog November 2026
datagram_data_blocked_updated, migration_state_updated,
timer_updated, key_updated, key_discarded,
recovery_parameters_set, recovery_metrics_updated,
congestion_state_updated, packet_lost, marked_for_retransmit,
ecn_state_updated
Description: Event definitions related to the QUIC transport
protocol.
Reference: This document
12. References
12.1. Normative References
[CDDL] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data
Definition Language (CDDL): A Notational Convention to
Express Concise Binary Object Representation (CBOR) and
JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610,
June 2019, <https://www.rfc-editor.org/rfc/rfc8610>.
[GREASEBIT]
Thomson, M., "Greasing the QUIC Bit", RFC 9287,
DOI 10.17487/RFC9287, August 2022,
<https://www.rfc-editor.org/rfc/rfc9287>.
[QLOG-MAIN]
Marx, R., Niccolini, L., Seemann, M., and L. Pardue,
"qlog: Structured Logging for Network Protocols", Work in
Progress, Internet-Draft, draft-ietf-quic-qlog-main-
schema-14, 6 July 2026,
<https://datatracker.ietf.org/doc/html/draft-ietf-quic-
qlog-main-schema-14>.
[QUIC-DATAGRAM]
Pauly, T., Kinnear, E., and D. Schinazi, "An Unreliable
Datagram Extension to QUIC", RFC 9221,
DOI 10.17487/RFC9221, March 2022,
<https://www.rfc-editor.org/rfc/rfc9221>.
[QUIC-RECOVERY]
Iyengar, J., Ed. and I. Swett, Ed., "QUIC Loss Detection
and Congestion Control", RFC 9002, DOI 10.17487/RFC9002,
May 2021, <https://www.rfc-editor.org/rfc/rfc9002>.
[QUIC-TLS] Thomson, M., Ed. and S. Turner, Ed., "Using TLS to Secure
QUIC", RFC 9001, DOI 10.17487/RFC9001, May 2021,
<https://www.rfc-editor.org/rfc/rfc9001>.
Marx, et al. Expires 6 May 2027 [Page 62]
Internet-Draft QUIC event definitions for qlog November 2026
[QUIC-TRANSPORT]
Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based
Multiplexed and Secure Transport", RFC 9000,
DOI 10.17487/RFC9000, May 2021,
<https://www.rfc-editor.org/rfc/rfc9000>.
[RESET-STREAM-AT]
Seemann, M. and K. Oku, "QUIC Stream Resets with Partial
Delivery", Work in Progress, Internet-Draft, draft-ietf-
quic-reliable-stream-reset-11, 6 September 2026,
<https://datatracker.ietf.org/doc/html/draft-ietf-quic-
reliable-stream-reset-11>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/rfc/rfc2119>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.
[RFC9221] Pauly, T., Kinnear, E., and D. Schinazi, "An Unreliable
Datagram Extension to QUIC", RFC 9221,
DOI 10.17487/RFC9221, March 2022,
<https://www.rfc-editor.org/rfc/rfc9221>.
[RFC9868] Touch, J. and C. Heard, Ed., "Transport Options for UDP",
RFC 9868, DOI 10.17487/RFC9868, October 2025,
<https://www.rfc-editor.org/rfc/rfc9868>.
12.2. Informative References
[RFC7301] Friedl, S., Popov, A., Langley, A., and E. Stephan,
"Transport Layer Security (TLS) Application-Layer Protocol
Negotiation Extension", RFC 7301, DOI 10.17487/RFC7301,
July 2014, <https://www.rfc-editor.org/rfc/rfc7301>.
Acknowledgements
Much of the initial work by Robin Marx was done at the Hasselt and KU
Leuven Universities.
Thanks to Jana Iyengar, Brian Trammell, Dmitri Tikhonov, Stephen
Petrides, Jari Arkko, Marcus Ihlar, Victor Vasiliev, Mirja
Kuehlewind, Jeremy Laine, Kazu Yamamoto, Christian Huitema, Hugo
Landau, Will Hawkins, Mathis Engelbart, Kazuho Oku, and Jonathan
Lennox for their feedback and suggestions.
Marx, et al. Expires 6 May 2027 [Page 63]
Internet-Draft QUIC event definitions for qlog November 2026
Change Log
This section is to be removed before publishing as an RFC.
Since draft-ietf-qlog-quic-events-13:
* Added datagram_dropped (#550)
* Wide range of editorial and consistency changes
Since draft-ietf-qlog-quic-events-12:
* Split frames_processed into 3 events (#513)
* Wide range of editorial changes
Since draft-ietf-qlog-quic-events-11:
* Updated several fields to be uint64 per QUIC spec
* Renamed error and error_code fields and logic (#473)
* Clarified parameters_set usage (#493)
* Replaced all length fields with raw.length (#495)
* Change loss_timer_updated to timer_updated (#496)
* Renamed path_assigned to tuple_assigned (#491)
* Reworked stream_state_updated (#497)
* Renamed owner to initiator (#498)
* Split up flags in PacketHeader (#478)
Since draft-ietf-qlog-quic-events-09:
* Several editorial changes
* Reworked QUICConnectionStarted to use PathEndpointInfo (#453)
* Consistent use of RawInfo and _bytes fields to log raw data (#450)
Since draft-ietf-qlog-quic-events-08:
* Removed individual categories and put every event in the single
quic event schema namespace. Major change (#439)
Marx, et al. Expires 6 May 2027 [Page 64]
Internet-Draft QUIC event definitions for qlog November 2026
* Renamed recovery:metrics_updated to quic:recovery_metrics_updated
and recovery:parameters_set to quic:recovery_parameters_set (#439)
* Added unknown_parameters field to parameters_set (#438)
* Added extra parameters to parameters_restored (#441)
Since draft-ietf-qlog-quic-events-07:
* TODO (we forgot...)
Since draft-ietf-qlog-quic-events-06:
* Added PathAssigned and MigrationStateUpdated events (#336)
* Added extension points to parameters_set and parameters_restored
(#400)
* Removed error_code_value from connection_closed (#386, #392)
* Renamed generation to key_phase for key_updated and key_discarded
(#390)
* Removed retry_token from packet_sent and packet_received (#389)
* Updated ALPN handling (#385)
* Added key_unavailable trigger to packet_dropped (#381)
* Updated several uint32 to uint64
* ProtocolEventBody is now called ProtocolEventData (#352)
* Editorial changes (#402, #404, #394, #393)
Since draft-ietf-qlog-quic-events-05:
* SecurityKeyUpdated: the new key is no longer mandatory to log
(#294)
* Added ECN related events and metadata (#263)
Since draft-ietf-qlog-quic-events-04:
* Updated guidance on logging events across connections (#279)
* Renamed 'transport' category to 'quic' (#302)
Marx, et al. Expires 6 May 2027 [Page 65]
Internet-Draft QUIC event definitions for qlog November 2026
* Added support for multiple packet numbers in
'quic:frames_processed' (#307)
* Added definitions for RFC9287 (QUIC GREASE Bit extension) (#311)
* Added definitions for RFC9221 (QUIC Datagram Frame extension)
(#310)
* (Temporarily) removed definitions for connection migration events
(#317)
* Editorial and formatting changes (#298, #299, #304, #306, #327)
Since draft-ietf-qlog-quic-events-03:
* Ensured consistent use of RawInfo to indicate raw wire bytes
(#243)
* Renamed UnknownFrame:raw_frame_type to :frame_type_value (#54)
* Renamed ConnectionCloseFrame:raw_error_code to :error_code_value
(#54)
* Changed triggers for packet_dropped (#278)
* Added entries to TransportError enum (#285)
* Changed minimum_congestion_window to uint64 (#288)
Since draft-ietf-qlog-quic-events-02:
* Renamed key_retired to key_discarded (#185)
* Added fields and events for DPLPMTUD (#135)
* Made packet_number optional in PacketHeader (#244)
* Removed connection_retried event placeholder (#255)
* Changed QuicFrame to a CDDL plug type (#257)
* Moved data definitions out of the appendix into separate sections
* Added overview Table of Contents
Marx, et al. Expires 6 May 2027 [Page 66]
Internet-Draft QUIC event definitions for qlog November 2026
Since draft-ietf-qlog-quic-events-01:
* Added Stateless Reset Token type (#122)
Since draft-ietf-qlog-quic-events-00:
* Change the data definition language from TypeScript to CDDL (#143)
Since draft-marx-qlog-event-definitions-quic-h3-02:
* These changes were done in preparation of the adoption of the
drafts by the QUIC working group (#137)
* Split QUIC and HTTP/3 events into two separate documents
* Moved RawInfo, Importance, Generic events and Simulation events to
the main schema document.
* Changed to/from value options of the data_moved event
Since draft-marx-qlog-event-definitions-quic-h3-01:
Major changes:
* Moved data_moved from http to transport. Also made the "from" and
"to" fields flexible strings instead of an enum (#111,#65)
* Moved packet_type fields to PacketHeader. Moved packet_size field
out of PacketHeader to RawInfo:length (#40)
* Made events that need to log packet_type and packet_number use a
header field instead of logging these fields individually
* Added support for logging retry, stateless reset and initial
tokens (#94,#86,#117)
* Moved separate general event categories into a single category
"generic" (#47)
* Added "transport:connection_closed" event (#43,#85,#78,#49)
* Added version_information and alpn_information events
(#85,#75,#28)
* Added parameters_restored events to help clarify 0-RTT behaviour
(#88)
Smaller changes:
Marx, et al. Expires 6 May 2027 [Page 67]
Internet-Draft QUIC event definitions for qlog November 2026
* Merged loss_timer events into one loss_timer_updated event
* Field data types are now strongly defined (#10,#39,#36,#115)
* Renamed qpack instruction_received and instruction_sent to
instruction_created and instruction_parsed (#114)
* Updated qpack:dynamic_table_updated.update_type. It now has the
value "inserted" instead of "added" (#113)
* Updated qpack:dynamic_table_updated. It now has an "owner" field
to differentiate encoder vs decoder state (#112)
* Removed push_allowed from http:parameters_set (#110)
* Removed explicit trigger field indications from events, since this
was moved to be a generic property of the "data" field (#80)
* Updated transport:connection_id_updated to be more in line with
other similar events. Also dropped importance from Core to Base
(#45)
* Added length property to PaddingFrame (#34)
* Added packet_number field to transport:frames_processed (#74)
* Added a way to generically log packet header flags (first 8 bits)
to PacketHeader
* Added additional guidance on which events to log in which
situations (#53)
* Added "simulation:scenario" event to help indicate simulation
details
* Added "packets_acked" event (#107)
* Added "datagram_ids" to the datagram_X and packet_X events to
allow tracking of coalesced QUIC packets (#91)
* Extended connection_state_updated with more fine-grained states
(#49)
Since draft-marx-qlog-event-definitions-quic-h3-00:
* Event and category names are now all lowercase
* Added many new events and their definitions
Marx, et al. Expires 6 May 2027 [Page 68]
Internet-Draft QUIC event definitions for qlog November 2026
* "type" fields have been made more specific (especially important
for PacketType fields, which are now called packet_type instead of
type)
* Events are given an importance indicator (issue #22)
* Event names are more consistent and use past tense (issue #21)
* Triggers have been redefined as properties of the "data" field and
updated for most events (issue #23)
Authors' Addresses
Robin Marx (editor)
Akamai
Email: rmarx@akamai.com
Luca Niccolini (editor)
Meta
Email: lniccolini@meta.com
Marten Seemann (editor)
Email: martenseemann@gmail.com
Lucas Pardue (editor)
Apple
Email: lucas@lucaspardue.com
Marx, et al. Expires 6 May 2027 [Page 69]