EpicGames/lore · error · anyhow::Error
No handshake data
Error message
No handshake data
What it means
After a QUIC connection is established, the server reads handshake data to learn the negotiated ALPN protocol. quinn's handshake_data() returns None before the handshake completes or if the data cannot be downcast to the expected HandshakeData type; get_protocol then fails with this error.
Solutions
- Wait for the connection to become established (connect()/accept() already yields connected conns — verify you are not using an early events API) before reading handshake data
- Ensure the downcast target matches the quinn crate version's HandshakeData type used when building TLS config
- Log connection state and retry/handle gracefully instead of failing hard
Example fix
// before
let data = connection.handshake_data().ok_or(anyhow!("No handshake data"))?;
// after
match connection.handshake_data().and_then(|h| h.downcast::<HandshakeData>().ok()) {
Some(h) => /* use h.protocol */,
None => { warn!("handshake data unavailable; dropping conn"); return Ok(()); }
} Defensive patterns
Strategy: try-catch
Validate before calling
if connection.handshake_data().is_none() {
// handshake not complete yet; wait or drop
} Type guard
fn handshake_protocol(conn: &quinn::Connection) -> Option<String> {
conn.handshake_data()?.downcast::<HandshakeData>().ok()?.protocol.clone().map(|b| String::from_utf8_lossy(&b).into_owned())
} Try / catch
match get_protocol(&connection) {
Err(e) if e.to_string().contains("No handshake data") => {
warn!("handshake data missing; closing connection gracefully");
return Ok(());
}
r => r?,
} Prevention
- Pin and track quinn crate versions; downcast targets can change between versions
- Treat handshake-data absence as a normal disconnect case, not a fatal error
- Avoid racing the connection state; only inspect after accept()/connect() resolves
When it happens
Trigger: A client connection is accepted but handshake_data() is still None (handshake not finished) or the downcast to HandshakeData fails; handle_conn then aborts the connection.
Common situations: Race where the connection is polled before handshake completion; quinn version change altering the handshake data box type so downcast fails; client disconnecting mid-handshake.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- No protocol found on request
- Missing QUIC certificate config
- Failed Quinn server start
- Failed client config
- Maintenance TLS is partially configured: cert_file and…
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/0ec95b063a67b64b.
Report an issue: GitHub.
Appendix: source
Thrown at lore-server/src/quic/quinn/quinn_server.rs:255
}
.in_current_span(),
)
);
}
}
.in_current_span(),
)
);
}
Ok(())
}
fn get_protocol(connection: &quinn::Connection) -> Result<String, anyhow::Error> {
let handshake_data = connection
.handshake_data()
.and_then(|h| h.downcast::<HandshakeData>().ok())
.ok_or(anyhow!("No handshake data"))?;
handshake_data
.protocol
.map(String::from_utf8)
.transpose()
.map_err(|e| anyhow!("Failed to decode protocol: {e:?}"))?
.ok_or(anyhow!("No protocol found on request"))
}
#[tracing::instrument(
name = "urc-quic",
skip_all,
fields(connection_id, protocol, correlation_id, repository_id)
)]
async fn handle_conn(
conn: quinn::Incoming,
monitor: TaskMonitor,
connection_metrics_interval: Duration,View on GitHub (pinned to 074eb0b0d1)