EpicGames/lore · error
Failed flush
Error message
Failed flush
What it means
This panic comes from request(): SendStream::flush returned Err. flush() waits for all buffered stream data to be acked-schedulable and fails under the same conditions as write — closed stream or dead connection.
Solutions
- Check for a close race: the handler finishing/closing right after consuming the header
- Verify the WriteError/CallDisconnect reason to distinguish ClosedStream from ConnectionLost
- Keep the server alive for the duration of the test (hold the QuinnServer handle, as Harness does with _server)
- If the race is inherent, downgrade flush to a best-effort match on ClosedStream
Example fix
// before
send.flush().await.expect("Failed flush");
// after
if let Err(e) = send.flush().await {
panic!("Failed flush: {:?} (connection reason: {:?})", e, connection.close_reason());
} Defensive patterns
Strategy: try-catch
Validate before calling
// before flush, confirm connection is alive
if connection.close_reason().is_some() { panic!("connection closed before flush"); } Type guard
fn conn_open(conn: &quinn::Connection) -> bool { conn.close_reason().is_none() } Try / catch
if let Err(quinn::WriteError::ClosedStream) = send.flush().await {
// benign race: handler closed the stream right after consuming the header
} else if let Err(e) = send.flush().await {
panic!("Failed flush: {e:?}");
} Prevention
- Treat ClosedStream on flush as a possible benign race in request/response helpers
- Check the handler hasn't closed the connection concurrently
- Avoid long gaps between write and flush to dodge idle timeouts
When it happens
Trigger: flush() after the peer stopped the stream, after connection close, or when the connection was lost between write() and flush().
Common situations: Server closed the connection immediately after reading the header so the flush wait fails; handler panicked between header read and processing; QUIC connection idle timeout fired during the flush await.
Related errors
- Failed to write header
- Failed to read response
- Failed to open additional stream
- Failed Quinn server start
- Failed to create client endpoint
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/091dff1d0b719ed4.
Report an issue: GitHub.
Appendix: source
Thrown at lore-server/src/quic/stream_handler.rs:850
_endpoint: Endpoint,
}
impl Harness {
/// Open an additional stream on the same connection.
async fn open_stream(&self) -> (SendStream, RecvStream) {
self.connection
.open_bi()
.await
.expect("Failed to open additional stream")
}
}
/// Send a request asking the handler for `behaviour`.
async fn request(send: &mut SendStream, behaviour: MockBehaviour, command_id: u32) {
send.write(&CommandHeader::new(behaviour.opcode(), command_id, 0).to_bytes())
.await
.expect("Failed to write header");
send.flush().await.expect("Failed flush");
}
/// Read one response header.
async fn response(recv: &mut RecvStream) -> CommandHeader {
let mut buffer = [0u8; 8];
recv.read_exact(&mut buffer)
.await
.expect("Failed to read response");
CommandHeader::from_bytes(&buffer)
}
/// Serve `factory` for `protocol` on a loopback endpoint and open a client stream to it.
///
/// The client skips certificate verification and presents none of its own; the mTLS tests
/// build their endpoints by hand because varying exactly that is what they test.
async fn serve_and_connect(
factory: Box<dyn StreamHandlerFactory>,
protocol: &'static str,View on GitHub (pinned to 074eb0b0d1)