tracel-ai/burn · critical

Can deserialize init handshake payload

Error message

Can deserialize init handshake payload

What it means

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.

Source

Thrown at crates/burn-remote/src/client/service.rs:181

        endpoint: &RemoteEndpoint,
        session_id: SessionId,
        device_index: u32,
    ) -> (DeviceSettings, u32) {
        let init_bytes: bytes::Bytes = rmp_serde::to_vec(&vec![RemoteMessage::Init(
            SessionInit::new(session_id, device_index, endpoint.authorization().to_vec()),
        )])
        .expect("Can serialize RemoteMessage::Init")
        .into();

        let result: Result<(DeviceSettings, u32), String> = async {
            request.send(init_bytes).await?;

            let msg = response
                .recv()
                .await?
                .expect("Server disconnected during initialization");
            let reply: TaskResponse =
                rmp_serde::from_slice(&msg).expect("Can deserialize init handshake payload");

            match reply.content {
                TaskResponseContent::Init(SessionInfo {
                    version,
                    settings,
                    device_count,
                    ..
                }) => {
                    if version != PROTOCOL_VERSION {
                        panic!(
                            "Server uses Burn Remote protocol version {version}, expected {PROTOCOL_VERSION}"
                        );
                    }
                    Ok((settings, device_count))
                }
                other => panic!("Expected Init response, got {other:?}"),
            }
        }

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Ensure client and server use the same burn version so the MessagePack wire format of TaskResponse matches.
  2. Confirm the endpoint port actually hosts a burn-remote server (the correct error for a wrong service is usually this deserialization panic).
  3. If behind a proxy, configure it to pass through binary/websocket frames unmodified.
  4. Enable server-side logging to inspect what was actually written to the response stream.
  5. If reproducible across matching versions, file a bug with a hex dump of the payload.

Example fix

// before: mismatched versions
// client: burn 0.15, server: burn 0.14  -> wire format differs
// after: pin matching versions on both sides
// Cargo.toml (client and server)
// burn = { version = "=0.15.0", features = ["remote"] }
Defensive patterns

Strategy: validation

Validate before calling

// Before connecting, confirm the endpoint serves a matching burn-remote version:
// 1) Check server binary version: `burn-remote-server --version` equals your client's burn crate version.
// 2) Confirm the port is the burn server, not another service:
//    nc -vz host port   (reachable) + inspect server logs for the incoming session.
fn version_matches(client: &str, server: &str) -> bool { client == server }

Try / catch

// Guard service creation so a protocol-mismatch panic is contained:
let svc = std::panic::catch_unwind(|| RemoteService::init(...));
if svc.is_err() { eprintln!("wire-format mismatch: align client/server burn versions"); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/4f0650a2cf0ba94f. Report an issue: GitHub.