cloudflare/quiche · error
error closing conn
Error message
error closing conn: {e:?} What it means
When the HTTP/0.9 response handling loop finishes, the client closes the connection with conn.close(true, 0x00, b"kthxbye") and panics if close returns an error other than Done. Done and Ok are treated as success (Done means already closed). Any other quiche::Error (e.g. InvalidState) indicates the connection is in an unexpected state at close time.
Solutions
- Inspect the debug-formatted error in the message to identify the underlying quiche::Error.
- Check earlier logs for transport errors that may have left the connection drained.
- Treat this as a symptom: fix the root-cause connection failure first.
- Update quiche if a state that should map to Done is being reported as an error.
Defensive patterns
Strategy: validation
Validate before calling
// Check connection state before attempting graceful close in client code
if !conn.is_closed() && conn.is_drained() { /* skip close */ } Prevention
- Treat this panic as a symptom of an earlier transport failure; review preceding errors.
- Keep network paths healthy; heavy loss increases close-time races.
- Track quiche updates for changes in close()/drained semantics.
When it happens
Trigger: Reaching the end of handle_responses while the underlying quiche::Connection is in a state where close() fails, e.g. after a fatal transport error already drained the connection.
Common situations: Connection already terminally errored or drained before the graceful close; race with peer-initiated close in lossy networks.
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
- Unsupported HTTP version and DATAGRAM protocol.
- TimedOut
- initial send failed
- datagram extension not enabled by peer
- initial send failed
AI-assisted analysis of cloudflare/quiche@9f96daa2c2 (2026-09-08).
Data as JSON: /api/errors/25e7af16fdcdf416.
Report an issue: GitHub.
Appendix: source
Thrown at apps/src/common.rs:542
debug!(
"{}/{} responses received",
self.reqs_complete, reqs_count
);
if self.reqs_complete == reqs_count {
info!(
"{}/{} response(s) received in {:?}, closing...",
self.reqs_complete,
reqs_count,
req_start.elapsed()
);
match conn.close(true, 0x00, b"kthxbye") {
// Already closed.
Ok(_) | Err(quiche::Error::Done) => (),
Err(e) => panic!("error closing conn: {e:?}"),
}
break;
}
}
}
}
}
fn report_incomplete(&self, start: &std::time::Instant) -> bool {
if self.reqs_complete != self.reqs.len() {
error!(
"connection timed out after {:?} and only completed {}/{} requests",
start.elapsed(),
self.reqs_complete,
self.reqs.len()
);
View on GitHub (pinned to 9f96daa2c2)