Summary

  • A valid CONNECTION_CLOSE immediately ends the QUIC connection and implicitly closes its open streams.
  • The sender enters closing and the receiver enters draining; both states retain different response obligations.
  • The close code and phrase describe transport evidence, not application completion, durable commit or root cause.

A protected CONNECTION_CLOSE is an authenticated peer transport signal. It proves that the receiving endpoint observed a valid close frame and that the connection entered the relevant termination path. It does not turn the network event into a business receipt. The distinction matters most when an operations ledger sees NO_ERROR and marks every in-flight workflow as complete.

QUIC ends the transport immediately. Open streams become closed immediately and may be treated as implicitly reset. The endpoint that sends the close enters closing; the peer that receives it enters draining. That transition is strong evidence about connection state, but it says nothing by itself about whether an application had negotiated a graceful shutdown, received every message, processed every request, committed durable state, compensated unfinished work or completed a transaction.

The frame variant must remain visible in the record. Frame type 0x1c carries QUIC-layer errors, including NO_ERROR, and includes the Triggering Frame Type field. That field identifies the frame that caused the error or is zero when it is unknown. Frame type 0x1d carries application-protocol error codes and has no Triggering Frame Type field. A transport code is not an application receipt, and NO_ERROR means only that the no-error transport code was used. The optional reason phrase is peer-supplied diagnostic text. It can be empty and has no language tag. Neither phrase nor code is a complete explanation of why a business process stopped.

The state machine also creates a timing boundary. Closing and draining normally persist for at least three current PTO intervals so delayed or reordered packets can be discarded cleanly. An endpoint may document another control that prevents late packets from provoking a response and permits earlier disposal. When either state ends, connection state is discarded and a later packet may receive a Stateless Reset. The discard time therefore belongs in the evidence record; it should not be confused with the instant of application completion.

Closing and draining are deliberately asymmetric. A closing endpoint keeps only enough information to identify connection packets and generate CONNECTION_CLOSE responses. It need not process received frames, and its close responses should be rate-limited while amplification limits still apply when incoming packets cannot be validated. A draining endpoint must send nothing. It may send at most one close packet before entering draining and then remains silent. A dashboard that treats silence as proof of successful shutdown is reading a state-machine rule as a business outcome.

Protection level is another essential qualification. After handshake confirmation, CONNECTION_CLOSE must be sent in a 1-RTT packet. Before confirmation, an endpoint may need to send close frames at more than one available protection level so the peer can process at least one copy. A client cannot assume that a server accepted a close sent only in 0-RTT. Thus a missing visible close is not automatically evidence that the peer ignored it. The ledger must preserve the protection level for each close copy and the direction in which it was observed.

Application evidence must be collected separately. If graceful shutdown was negotiated, that negotiation needs its own record. Each operation needs independent evidence of acceptance, durable commit, compensation and completion. Incident attribution needs evidence independent of the close frame. A reason phrase can guide diagnosis, but it cannot replace those records. The same discipline applies whether the close is deliberate, follows a protocol violation or arrives while work remains in flight.

The practical control is simple but demanding: record what QUIC proves, then stop. Do not let a transport close rewrite application state. A workflow may have completed before the close, may have been accepted but not committed, or may have been interrupted with no compensation. CONNECTION_CLOSE cannot choose among those possibilities.