cloudflare/quiche · critical
The provided buffer is too large
Error message
The provided buffer is too large
What it means
Defensive size guard in the H3 FFI wrapper quiche_h3_send_body. body_len is size_t but bytes sent are returned as ssize_t; a body length above ssize_t::MAX cannot be represented in the return value, so the wrapper panics instead of returning an ambiguous value.
Solutions
- Pass the actual body buffer length, <= SSIZE_MAX
- Validate or chunk large bodies before sending
- Fix signed-length bugs at the call site
Example fix
// before quiche_h3_send_body(h3, conn, id, body, (size_t)len, fin); // after if (len < 0 || (size_t)len > SSIZE_MAX) return -1; quiche_h3_send_body(h3, conn, id, body, (size_t)len, fin);
Defensive patterns
Strategy: validation
Validate before calling
if (body_len < 0 || (size_t)body_len > SSIZE_MAX) return -1;
Prevention
- Send bodies in bounded chunks rather than one huge buffer
- Validate body lengths from untrusted sources
- Use size_t/ssize_t consistently in H3 C callers
When it happens
Trigger: Calling quiche_h3_send_body() with body_len > SSIZE_MAX (typically a negative C length cast to size_t).
Common situations: Sign/overflow errors in C HTTP/3 applications, untrusted body sizes, fuzzing of the h3 FFI boundary.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- invalid CC frame in qlog input, no error code
- Expected stream_send on stream
- Expected stream_send on stream
- The provided buffer is too large
- tokio task ID already in use
AI-assisted analysis of cloudflare/quiche@9f96daa2c2 (2026-09-08).
Data as JSON: /api/errors/558b983e292f92d0.
Report an issue: GitHub.
Appendix: source
Thrown at quiche/src/h3/ffi.rs:308
quic_conn,
stream_id,
&headers,
is_trailer_section,
fin,
) {
Ok(_) => 0,
Err(e) => e.to_c() as c_int,
}
}
#[no_mangle]
pub extern "C" fn quiche_h3_send_body(
conn: &mut h3::Connection, quic_conn: &mut Connection, stream_id: u64,
body: *const u8, body_len: size_t, fin: bool,
) -> ssize_t {
if body_len > <ssize_t>::MAX as usize {
panic!("The provided buffer is too large");
}
let body = unsafe { slice::from_raw_parts(body, body_len) };
match conn.send_body(quic_conn, stream_id, body, fin) {
Ok(v) => v as ssize_t,
Err(e) => e.to_c(),
}
}
#[no_mangle]
pub extern "C" fn quiche_h3_recv_body(
conn: &mut h3::Connection, quic_conn: &mut Connection, stream_id: u64,
out: *mut u8, out_len: size_t,
) -> ssize_t {
if out_len > <ssize_t>::MAX as usize {
panic!("The provided buffer is too large");View on GitHub (pinned to 9f96daa2c2)