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

  1. 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
  2. Ensure the downcast target matches the quinn crate version's HandshakeData type used when building TLS config
  3. 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

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

Related errors


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)