cloudflare/quiche · error
Expected stream_send on stream
Error message
Expected stream_send on stream {} to write {} bytes, got {} What it means
This panic comes from h3i's action validation when a script asserts that quiche's stream_send wrote an exact number of bytes, but it wrote a different amount. h3i executes scripted H3 actions against a connection and verifies each ExpectedStreamSendResult; a byte-count mismatch means the connection or stream state differed from what the script assumed (e.g. stream already closed, flow control limited the write). It is a test-harness assertion failure, not a runtime error you can catch in the library.
Solutions
- Print the actual bytes written and compare with the expected count; adjust the script's expected value or the payload size.
- Check the stream's available send capacity (flow control / stream state) before the action; add a wait or frame-action for the peer's MAX_STREAM_DATA/MAX_DATA update.
- If exact length doesn't matter, relax the assertion to ExpectedStreamSendResult::OkAny or just assert no error.
Example fix
// before ExpectedStreamSendResult::OkExact(1200), // after ExpectedStreamSendResult::OkExact(written) // align with actual flow-control-limited write, or use OkAny
Defensive patterns
Strategy: validation
Validate before calling
// before executing the action
assert!(expected_bytes <= conn.stream_capacity(stream_id).unwrap_or(0),
"stream {} cannot accept {} bytes", stream_id, expected_bytes); Prevention
- Check stream_capacity / stream_writable before asserting exact write sizes.
- Prefer OkAny or error-tolerant expectations unless byte-exactness is the test's purpose.
When it happens
Trigger: Executing an ExecuteAction with ExpectedStreamSendResult::OkExact(n) where quiche_conn_stream_send returns Ok(m) with m != n on the given stream_id.
Common situations: Scripts written against one server reused against another with different flow-control windows; sending on a stream that already had partial data buffered; stream capacity reduced by peer MAX_STREAM_DATA after the script was authored.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Expected stream_send on stream
- Expected stream_send on stream
- Expected stream_send on stream
- Expected stream_send on stream
- Error creating qlog file attempted path was
AI-assisted analysis of cloudflare/quiche@9f96daa2c2 (2026-09-08).
Data as JSON: /api/errors/cf718786ed221505.
Report an issue: GitHub.
Appendix: source
Thrown at h3i/src/client/mod.rs:125
pub(crate) type StreamParserMap = HashMap<u64, FrameParser>;
fn validate_stream_send_result(
result: quiche::Result<usize>, expected: &ExpectedStreamSendResult,
stream_id: u64,
) {
match expected {
ExpectedStreamSendResult::Ok => {
result.unwrap_or_else(|err| {
panic!(
"Expected stream_send on stream {} to succeed, but got: {:?}",
stream_id, err
)
});
},
ExpectedStreamSendResult::OkExact(expected_bytes) => {
match result {
Ok(actual_bytes) if actual_bytes == *expected_bytes => {},
Ok(actual_bytes) => panic!(
"Expected stream_send on stream {} to write {} bytes, got {}",
stream_id, expected_bytes, actual_bytes
),
Err(err) => panic!(
"Expected stream_send on stream {} to write {} bytes, got error: {:?}",
stream_id, expected_bytes, err
),
}
},
ExpectedStreamSendResult::Error(expected_err) => {
match result {
Ok(written) => panic!(
"Expected stream_send on stream {} to fail with {:?}, but wrote {} bytes",
stream_id, expected_err, written
),
Err(actual_err) if &actual_err == expected_err => {},
Err(actual_err) => panic!(
"Expected stream_send on stream {} to fail with {:?}, got {:?}",View on GitHub (pinned to 9f96daa2c2)