EpicGames/lore · error
Failed socket setup
Error message
Failed socket setup
What it means
serve_and_connect() binds an ephemeral UDP socket on 127.0.0.1:0 and then calls local_addr() to learn the chosen port before dropping the socket; this expect panics if local_addr() errors. It only fails if the OS reports the socket invalid, i.e. the bind or socket state is broken.
Solutions
- Retry the ephemeral bind if local_addr fails (transient OS issue)
- Check fd limits (ulimit -n) when running many tests in parallel
- Run outside sandboxed/privileged-restricted environments to rule out getsockname blocking
- If intermittent, restructure to keep the socket open and pass it to Quinn instead of bind/drop
Example fix
// before
let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
let server_addr = socket.local_addr().expect("Failed socket setup");
// after
let socket = UdpSocket::bind("127.0.0.1:0").expect("bind failed");
let server_addr = socket.local_addr().expect("local_addr after successful bind failed"); Defensive patterns
Strategy: validation
Validate before calling
let socket = std::net::UdpSocket::bind("127.0.0.1:0").expect("ephemeral bind failed");
let server_addr = socket.local_addr().expect("local_addr failed");
assert!(server_addr.port() > 0); Type guard
fn bound_addr(s: &std::net::UdpSocket) -> Option<std::net::SocketAddr> { s.local_addr().ok() } Prevention
- Prefer keeping the bound socket open and passing it to the QUIC stack instead of bind/drop
- Raise fd limits for large parallel test runs
- Avoid running tests in sandboxes that block getsockname
When it happens
Trigger: UdpSocket::bind succeeded but the fd was somehow closed/invalid by the time local_addr() runs (double-drop, fd exhaustion, sandboxed environment blocking getsockname).
Common situations: Running tests in restricted containers/sandboxes where socket metadata calls fail; file-descriptor exhaustion in large parallel test suites; rare OS-level socket errors.
Related errors
- Failed to create client endpoint
- Failed to setup bidirectional channel
- Failed to open additional stream
- Failed to write header
- Failed flush
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/66b6d1bcfca9ccef.
Report an issue: GitHub.
Appendix: source
Thrown at lore-server/src/quic/stream_handler.rs:871
/// 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,
) -> Harness {
let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
let server_addr = socket.local_addr().expect("Failed socket setup");
drop(socket);
let (cert_path, key_path, _) = server_certs().expect("Bad cert paths");
let server = QuinnServer::start(
QuinnConfigBuilder::new()
.address(server_addr)
.cert_file(cert_path)
.pkey_file(key_path)
.stream_handler_factory(factory)
.build()
.unwrap(),
)
.expect("Failed Quinn server start");
let mut crypto_config = rustls::ClientConfig::builder()
.dangerous()
.with_custom_certificate_verifier(insecure_client_auth::SkipServerVerification::new())
.with_no_client_auth();View on GitHub (pinned to 074eb0b0d1)