{"record":{"id":"4f0650a2cf0ba94f","repo":"tracel-ai/burn","slug":"can-deserialize-init-handshake-payload","errorCode":null,"errorMessage":"Can deserialize init handshake payload","messagePattern":"Can deserialize init handshake payload","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/burn-remote/src/client/service.rs","lineNumber":181,"sourceCode":"        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:?}\"),\n            }\n        }","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-remote/src/client/service.rs#L163-L199","documentation":"After receiving the handshake reply bytes from the server, the client deserializes them into a `TaskResponse` with rmp_serde and expects success. A panic here means bytes arrived but are not a valid `TaskResponse` in the expected MessagePack wire format — i.e. the peer is speaking a different protocol or the stream is corrupted.","triggerScenarios":"Connecting to a server running an incompatible burn-remote protocol version or a different service entirely on that port; a proxy/middlebox mangling binary frames; a custom server implementation emitting a differently-shaped response; wire corruption (rare) on an unstable transport.","commonSituations":"Client and server built from different burn versions (e.g. after a breaking wire-format change); pointing the client at the wrong port (another binary-protocol service); custom Rust server that writes its own response format; WebSocket proxy re-encoding binary frames as text.","solutions":["Ensure client and server use the same burn version so the MessagePack wire format of TaskResponse matches.","Confirm the endpoint port actually hosts a burn-remote server (the correct error for a wrong service is usually this deserialization panic).","If behind a proxy, configure it to pass through binary/websocket frames unmodified.","Enable server-side logging to inspect what was actually written to the response stream.","If reproducible across matching versions, file a bug with a hex dump of the payload."],"exampleFix":"// before: mismatched versions\n// client: burn 0.15, server: burn 0.14  -> wire format differs\n// after: pin matching versions on both sides\n// Cargo.toml (client and server)\n// burn = { version = \"=0.15.0\", features = [\"remote\"] }","handlingStrategy":"validation","validationCode":"// Before connecting, confirm the endpoint serves a matching burn-remote version:\n// 1) Check server binary version: `burn-remote-server --version` equals your client's burn crate version.\n// 2) Confirm the port is the burn server, not another service:\n//    nc -vz host port   (reachable) + inspect server logs for the incoming session.\nfn version_matches(client: &str, server: &str) -> bool { client == server }","typeGuard":null,"tryCatchPattern":"// Guard service creation so a protocol-mismatch panic is contained:\nlet svc = std::panic::catch_unwind(|| RemoteService::init(...));\nif svc.is_err() { eprintln!(\"wire-format mismatch: align client/server burn versions\"); }","preventionTips":["Pin identical burn versions on client and server (e.g. burn = \"=0.15.0\").","Never point a burn client at a non-burn binary-protocol port.","Configure proxies to pass binary/websocket frames untouched.","Smoke-test the handshake after every deployment that bumps burn.","Log server-side response bytes when debugging wire issues."],"tags":["serialization","protocol-mismatch","handshake","burn-remote"],"backgroundTag":"msgpack-deserialization-failed","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"}