cloudflare/quiche · error
initial send failed
Error message
initial send failed
What it means
In quiche-client's connect(), the very first packet sent (the QUIC initial) is produced by conn.send() and unwrapped with expect("initial send failed"). If the connection cannot encode the initial packet (e.g. the connection is already in an error/done state), the client panics with this message.
Solutions
- Ensure the `out` buffer is at least MAX_DATAGRAM_SIZE and quiche's MIN_CLIENT_INITIAL_LEN is respected
- Verify TLS certificate/key files load correctly before connect
- Check the log/trace output for the underlying quiche error to see why the initial couldn't be produced
- Replace the expect with proper error handling if embedding this code
Example fix
// before
let (write, send_info) = conn.send(&mut out).expect("initial send failed");
// after
let (write, send_info) = match conn.send(&mut out) {
Ok(v) => v,
Err(e) => { eprintln!("initial send failed: {e}"); return Err(e.into()); }
}; Defensive patterns
Strategy: try-catch
Validate before calling
assert!(out.len() >= quiche::MAX_DATAGRAM_SIZE); assert!(conn.is_established() || !conn.is_closed());
Try / catch
let (write, send_info) = conn.send(&mut out)
.map_err(|e| anyhow!("initial send failed: {e}"))?; Prevention
- Size the send buffer at least MAX_DATAGRAM_SIZE and respect MIN_CLIENT_INITIAL_LEN
- Verify TLS cert/key load before creating the connection
- Log the underlying quiche::Error instead of panicking with expect
When it happens
Trigger: conn.send(&mut out) returns Err on the first send attempt after connection creation — typically because the connection state rejects generating an initial packet (connection already closed/done, config issue).
Common situations: Extremely small send buffer (out) too short for the initial packet plus TLS data; connection immediately closed due to invalid config (bad TLS cert/key, invalid local address); QUIC version mismatches causing early close.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- --connect-to is expected to be a string containing an IPv4…
- datagram extension not enabled by peer
- initial send failed
- error closing conn
- The provided buffer is too large
AI-assisted analysis of cloudflare/quiche@9f96daa2c2 (2026-09-08).
Data as JSON: /api/errors/b01bc85356bc0d72.
Report an issue: GitHub.
Appendix: source
Thrown at apps/src/client.rs:232
format!("{} id={}", "quiche-client qlog", id),
);
}
}
if let Some(session_file) = &args.session_file {
if let Ok(session) = std::fs::read(session_file) {
conn.set_session(&session).ok();
}
}
info!(
"connecting to {:} from {:} with scid {:?}",
peer_addr,
socket.local_addr().unwrap(),
scid,
);
let (write, send_info) = conn.send(&mut out).expect("initial send failed");
while let Err(e) = socket.send_to(&out[..write], send_info.to) {
if e.kind() == std::io::ErrorKind::WouldBlock {
trace!(
"{} -> {}: send() would block",
socket.local_addr().unwrap(),
send_info.to
);
continue;
}
return Err(ClientError::Other(format!("send() failed: {e:?}")));
}
trace!("written {write}");
let app_data_start = std::time::Instant::now();
View on GitHub (pinned to 9f96daa2c2)