{"record":{"id":"4575bf3a91a223fe","repo":"EpicGames/lore","slug":"no-protocol-found-on-request","errorCode":null,"errorMessage":"No protocol found on request","messagePattern":"No protocol found on request","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"lore-server/src/quic/quinn/quinn_server.rs","lineNumber":262,"sourceCode":"            )\n        );\n    }\n\n    Ok(())\n}\n\nfn get_protocol(connection: &quinn::Connection) -> Result<String, anyhow::Error> {\n    let handshake_data = connection\n        .handshake_data()\n        .and_then(|h| h.downcast::<HandshakeData>().ok())\n        .ok_or(anyhow!(\"No handshake data\"))?;\n\n    handshake_data\n        .protocol\n        .map(String::from_utf8)\n        .transpose()\n        .map_err(|e| anyhow!(\"Failed to decode protocol: {e:?}\"))?\n        .ok_or(anyhow!(\"No protocol found on request\"))\n}\n\n#[tracing::instrument(\n    name = \"urc-quic\",\n    skip_all,\n    fields(connection_id, protocol, correlation_id, repository_id)\n)]\nasync fn handle_conn(\n    conn: quinn::Incoming,\n    monitor: TaskMonitor,\n    connection_metrics_interval: Duration,\n    stream_handler_factory: Arc<Box<dyn StreamHandlerFactory>>,\n) -> anyhow::Result<()> {\n    let connection = conn.await?;\n\n    let protocol = get_protocol(&connection)?;\n\n    let connection_id = connection.stable_id();","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/EpicGames/lore/blob/074eb0b0d1194c997d7cf28b55519e3e197b3e23/lore-server/src/quic/quinn/quinn_server.rs#L244-L280","documentation":"Thrown by get_protocol when the TLS handshake data for an accepted QUIC connection exists but carries no negotiated ALPN protocol (the protocol field is None). Since this server requires every connection to identify its service via ALPN, a client that connected without offering (or agreeing on) any ALPN identifier is rejected here during handle_conn processing.","triggerScenarios":"A client connects without offering any ALPN identifiers, or offers none that the server advertised, so no protocol is selected during the handshake.","commonSituations":"Raw QUIC clients (e.g. test scripts, curl --http3 with ALPN disabled) connecting without setting ALPN; server and client ALPN lists disjoint so negotiation yields nothing; misconfigured client TLS settings.","solutions":["Configure the client to offer the server's supported ALPN protocols (see stream_handler_factory.supported_protocols())","Check that server-side TLS config advertises the factory's ALPNs (server_config with alpn_protocols)","Verify client quic/tls library sends ALPN in the ClientHello"],"exampleFix":"// client, before\nlet mut client = quinn::ClientConfig::new(crypto);\n// after\nlet mut transport = quinn::TransportConfig::default();\nlet mut client = quinn::ClientConfig::new(crypto);\nclient.alpn_protocols = vec![b\"lore/1\".to_vec()];","handlingStrategy":"validation","validationCode":"// client side: ensure ALPN offered before connecting\nassert!(!client_config.alpn_protocols.is_empty(), \"client must offer at least one ALPN\");","typeGuard":null,"tryCatchPattern":"match get_protocol(&connection) {\n    Err(e) if e.to_string().contains(\"No protocol found\") => {\n        warn!(\"client offered no ALPN; rejecting\");\n        return Ok(());\n    }\n    r => r?,\n}","preventionTips":["Document required ALPNs for clients and validate in client SDKs","Keep server and client ALPN lists in sync across releases","Test connectivity with a client that has ALPN disabled to confirm graceful handling"],"tags":["rust","quic","alpn","tls"],"backgroundTag":"missing-required-argument","analyzedSha":"074eb0b0d1194c997d7cf28b55519e3e197b3e23","analyzedAt":"2026-09-13T09:00:57.509Z","contentChangedAt":"2026-09-13T09:00:57.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}