cloudflare/quiche · error

invalid CC frame in qlog input, no error code

Error message

invalid CC frame in qlog input, no error code

What it means

When converting qlog events into h3i actions, a connection_close event without an error_code field is turned into quiche::ConnectionError, whose error_code field is mandatory. The code calls .expect() on the missing Option, panicking with this message. The comment references issue #1731 (Option should be removed upstream).

Solutions

  1. Add an error_code field to the connection_close event in the qlog input.
  2. Regenerate the qlog from a tool that always records the error code.
  3. Default missing error codes (e.g. unwrap_or(0)) and remove the panic, per upstream issue #1731.

Example fix

// before
error_code: error_code.expect("invalid CC frame in qlog input, no error code"),
// after
error_code: error_code.unwrap_or(0), // or 0x0c NO_ERROR for app closes
Defensive patterns

Strategy: validation

Validate before calling

let error_code = event.error_code
    .ok_or_else(|| anyhow!("connection_close event missing error_code in qlog"))?;

Try / catch

let error_code = match error_code {
    Some(c) => c,
    None => { eprintln!("skipping CC frame without error code"); continue; }
};

Prevention

When it happens

Trigger: Replaying a qlog file whose CONNECTION_CLOSE event lacks an error code — common for transport-level closes or qlogs emitted by other implementations.

Common situations: Replaying netlog/qlog traces from browsers or servers that omit error_code; hand-edited qlog files; older qlog drafts with optional error codes.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of cloudflare/quiche@9f96daa2c2 (2026-09-08). Data as JSON: /api/errors/5e0ac41167f5b092. Report an issue: GitHub.

Appendix: source

Thrown at h3i/src/recordreplay/qlog.rs:431

                    QuicFrame::ConnectionClose {
                        error_space,
                        error_code,
                        reason,
                        ..
                    } => {
                        let is_app = matches!(
                            error_space.as_ref().expect(
                                "invalid CC frame in qlog input, no error space"
                            ),
                            ErrorSpace::Application
                        );

                        actions.push(Action::ConnectionClose {
                            error: quiche::ConnectionError {
                                is_app,
                                // TODO: remove unwrap when https://github.com/cloudflare/quiche/issues/1731
                                // is done
                                error_code: error_code.expect("invalid CC frame in qlog input, no error code"),
                                reason: reason
                                    .as_ref()
                                    .map(|s| s.as_bytes().to_vec())
                                    .unwrap_or_default(),
                            },
                        })
                    },

                    QuicFrame::Stream { stream_id, fin, .. } => {
                        let fin = fin.unwrap_or_default();

                        if fin {
                            actions.push(Action::StreamBytes {
                                stream_id: *stream_id,
                                fin_stream: true,
                                bytes: vec![],
                                expected_result: Default::default(),
                            });

View on GitHub (pinned to 9f96daa2c2)