cloudflare/quiche · error

Expected stream_send on stream

Error message

Expected stream_send on stream {} to write {} bytes, got error: {:?}

What it means

h3i's stream_send validation panics when the script expected an exact byte count but quiche's stream_send returned an error instead of writing bytes. This means the stream could not accept data at all — commonly because it was closed, reset, or the connection is in an error/drain state. It is an assertion failure inside the h3i test driver.

Solutions

  1. Inspect the debug-printed error to identify which stream/connection state failed, and fix the script ordering so the send precedes any close/reset.
  2. If an error is legitimate, change the expectation to ExpectedStreamSendResult::Error(expected_err).
  3. Verify the stream_id exists and was created by an earlier action (headers/data frame) in the script.

Example fix

// before
ExpectedStreamSendResult::OkExact(512),
// after
ExpectedStreamSendResult::Error(quiche::h3::Error::StreamStopped),
Defensive patterns

Strategy: validation

Validate before calling

// ensure the stream is still open before asserting a successful send
if !conn.stream_writable(stream_id, 1).unwrap_or(false) {
    // adjust expectation to an Error variant or skip the action
}

Prevention

When it happens

Trigger: ExecuteAction with ExpectedStreamSendResult::OkExact(n) where quiche stream_send returns Err (e.g. StreamStopped, FlowControl, Done on a closed stream).

Common situations: Sending on a stream the peer already reset; writing after the connection hit an error; script ordering issues where a close/reset frame action runs before the send.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at h3i/src/client/mod.rs:129

    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 {:?}",
                    stream_id, expected_err, actual_err
                ),
            }
        },

View on GitHub (pinned to 9f96daa2c2)