{"record":{"id":"4df974a0eb9a8beb","repo":"tracel-ai/burn","slug":"server-disconnected-during-initialization","errorCode":null,"errorMessage":"Server disconnected during initialization","messagePattern":"Server disconnected during initialization","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/burn-remote/src/client/service.rs","lineNumber":179,"sourceCode":"        request: &mut SubmitChannel,\n        response: &mut ResponseChannel,\n        endpoint: &RemoteEndpoint,\n        session_id: SessionId,\n        device_index: u32,\n    ) -> (DeviceSettings, u32) {\n        let init_bytes: bytes::Bytes = rmp_serde::to_vec(&vec![RemoteMessage::Init(\n            SessionInit::new(session_id, device_index, endpoint.authorization().to_vec()),\n        )])\n        .expect(\"Can serialize RemoteMessage::Init\")\n        .into();\n\n        let result: Result<(DeviceSettings, u32), String> = async {\n            request.send(init_bytes).await?;\n\n            let msg = response\n                .recv()\n                .await?\n                .expect(\"Server disconnected during initialization\");\n            let reply: TaskResponse =\n                rmp_serde::from_slice(&msg).expect(\"Can deserialize init handshake payload\");\n\n            match reply.content {\n                TaskResponseContent::Init(SessionInfo {\n                    version,\n                    settings,\n                    device_count,\n                    ..\n                }) => {\n                    if version != PROTOCOL_VERSION {\n                        panic!(\n                            \"Server uses Burn Remote protocol version {version}, expected {PROTOCOL_VERSION}\"\n                        );\n                    }\n                    Ok((settings, device_count))\n                }\n                other => panic!(\"Expected Init response, got {other:?}\"),","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-remote/src/client/service.rs#L161-L197","documentation":"During session init the client sends `RemoteMessage::Init` on the request stream and waits for one message on the response stream. `response.recv()` returns `Ok(None)` when the stream was closed by the peer without delivering a message; this expect turns that into a panic. It means the server accepted the connection but terminated the response stream before answering the handshake.","triggerScenarios":"The burn-remote server process crashes or exits between accepting the channels and replying to the Init message; the server closes the connection due to failed authorization or an immediate internal error; a proxy/firewall or idle timeout kills the connection right after it opens; connecting to a port where a non-burn server is listening and then closes the stream.","commonSituations":"Server deployed with a wrong authorization token and drops the session; server OOM-killed or restarted mid-handshake; connecting to the wrong host/port (e.g. a plain TCP echo or a different service); Kubernetes/load-balancer idle timeout shorter than connection setup; wasm client hitting a server behind a reverse proxy that buffers websockets.","solutions":["Check the server is running and inspect its logs for a crash or rejection at handshake time.","Verify the server address/port passed to the RemoteEndpoint points at a burn-remote server of the matching version.","Confirm the authorization token in the endpoint matches the server's configured token.","Add network-level checks: keepalives/firewall rules/proxy timeouts so the stream is not closed during setup.","Retry connecting — transient server restarts produce exactly this one-shot failure."],"exampleFix":"// before: fire-and-forget connect to a possibly stale address\nlet device = RemoteDevice::new(&\"ws://stale-host:3000\".parse().unwrap());\n// after: ensure the server is up and address is correct before connecting\nassert!(server_addr reachable); // e.g. TCP probe / health check\nlet device = RemoteDevice::new(&current_endpoint_from_config());","handlingStrategy":"retry","validationCode":"// Probe the server before creating a remote device:\nuse std::net::TcpStream;\nfn server_reachable(addr: std::net::SocketAddr) -> bool {\n    TcpStream::connect_timeout(&addr, std::time::Duration::from_secs(3)).is_ok()\n}\n// Also verify process liveness (systemd status / k8s probe) and that auth token matches server config.","typeGuard":null,"tryCatchPattern":"// handshake_async surfaces the failure as a String error then panics; isolate init:\nlet result = std::panic::catch_unwind(|| RemoteService::init(...));\nmatch result {\n    Ok(svc) => svc,\n    Err(_) => { log::warn!(\"server dropped init handshake; retrying\"); backoff_retry(init, 3); }\n}","preventionTips":["Run the burn-remote server under a supervisor (systemd/k8s restart policy) so it never stays down.","Match client and server authorization tokens exactly.","Use health checks / readiness probes before clients connect.","Keep proxy/idle timeouts longer than connection setup.","Pin matching burn versions on client and server."],"tags":["network","disconnection","handshake","burn-remote"],"backgroundTag":"server-disconnected","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}