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

  1. Ensure the `out` buffer is at least MAX_DATAGRAM_SIZE and quiche's MIN_CLIENT_INITIAL_LEN is respected
  2. Verify TLS certificate/key files load correctly before connect
  3. Check the log/trace output for the underlying quiche error to see why the initial couldn't be produced
  4. 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

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


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)