{"record":{"id":"f29b799dfb4ed83f","repo":"cloudflare/quiche","slug":"datagram-extension-not-enabled-by-peer","errorCode":null,"errorMessage":"datagram extension not enabled by peer","messagePattern":"datagram extension not enabled by peer","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"h3i/src/client/mod.rs","lineNumber":303,"sourceCode":"            log::info!(\n                \"stream bytes tx id={} len={} fin={}\",\n                stream_id,\n                bytes.len(),\n                fin_stream\n            );\n            let result = conn.stream_send(*stream_id, bytes, *fin_stream);\n            validate_stream_send_result(result, expected_result, *stream_id);\n\n            stream_parsers\n                .entry(*stream_id)\n                .or_insert_with(|| FrameParser::new(*stream_id));\n        },\n\n        Action::SendDatagram { payload } => {\n            log::info!(\"dgram tx len={}\", payload.len(),);\n\n            conn.dgram_send(payload)\n                .expect(\"datagram extension not enabled by peer\");\n        },\n\n        Action::ResetStream {\n            stream_id,\n            error_code,\n        } => {\n            log::info!(\n                \"reset_stream stream_id={stream_id} error_code={error_code}\"\n            );\n            if let Err(e) = conn.stream_shutdown(\n                *stream_id,\n                quiche::Shutdown::Write,\n                *error_code,\n            ) {\n                log::error!(\"can't send reset_stream: {e}\");\n                // Clients cannot reset streams they do not own. If attempted,\n                // `stream_shutdown()` fails and no parser should be created.\n                return;","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/cloudflare/quiche/blob/9f96daa2c22a4468b0036fb0a0a3894eee6498b8/h3i/src/client/mod.rs#L285-L321","documentation":"h3i's execute_action sends a QUIC datagram via conn.dgram_send() and panics with this message if the call returns an error. The QUIC datagram extension (RFC 9221) must be negotiated by both peers during the handshake; if the server did not advertise the DATAGRAM extension (or its max_datagram_frame_size is 0), sending fails and this expect() turns that into a panic.","triggerScenarios":"Running an h3i action file containing a SendDatagram action against a server that did not negotiate the datagram extension, or before the handshake completed.","commonSituations":"Pointing h3i at a server without QUIC datagram support enabled; missing --enable-datagram / max_datagram_frame_size config on the peer; testing MASQUE/CONNECT-UDP against a plain HTTP/3 server.","solutions":["Enable datagram support on the server (advertise max_datagram_frame_size, e.g. quiche Config.enable_dgram(true,..)).","Remove the SendDatagram action from the h3i action file, or gate it on the peer's negotiated extensions.","Check conn.dgram_send() result in h3i and surface a graceful error instead of panicking."],"exampleFix":"// before (h3i action file)\n{\"action\":\"send_datagram\",\"payload\":\"...\"}\n// after\n{\"action\":\"send_frame\",\"stream_id\":0,\"frame\":{\"type\":\"settings\",...}} // or enable datagrams on the server first","handlingStrategy":"validation","validationCode":"if !conn.dgram_max_writable_len().map_or(false, |l| l > 0) {\n    eprintln!(\"peer did not negotiate datagram extension; skipping SendDatagram\");\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"// replace expect with error propagation\nconn.dgram_send(payload).unwrap_or_else(|e| eprintln!(\"dgram_send failed: {e}\"));","preventionTips":["Check conn.dgram_max_writable_len() > 0 before sending datagrams.","Enable datagram support on both client and server configs.","Gate SendDatagram actions behind a negotiated-extension check in action files."],"tags":["quic","datagram","negotiation","panic"],"backgroundTag":"feature-not-enabled","analyzedSha":"9f96daa2c22a4468b0036fb0a0a3894eee6498b8","analyzedAt":"2026-09-08T11:27:09.536Z","contentChangedAt":"2026-09-08T11:27:09.536Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}