{"record":{"id":"89afb89c687f58b9","repo":"vllm-project/vllm","slug":"transport-error","errorCode":null,"errorMessage":"transport error","messagePattern":"transport error","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"rust/src/engine-core-client/src/error.rs","lineNumber":35,"sourceCode":"    #[error(\"messagepack encode failed for {target_type}: {message}\")]\n    Encode {\n        target_type: &'static str,\n        message: String,\n    },\n    #[error(\"messagepack decode failed for {target_type}: {message}\")]\n    Decode {\n        target_type: &'static str,\n        message: String,\n    },\n    #[error(\"messagepack value decode failed\")]\n    ValueDecode(#[from] rmpv::decode::Error),\n    #[error(\"messagepack ext value decode failed: {message}\")]\n    ExtValueDecode { message: String },\n    #[error(\"invalid structured outputs params: {message}\")]\n    InvalidStructuredOutputsParams { message: String },\n    #[error(\"io error\")]\n    Io(#[from] std::io::Error),\n    #[error(\"transport error\")]\n    Transport(#[from] zeromq::ZmqError),\n    #[error(\"ZMQ runtime task failed\")]\n    ZmqRuntimeTask(#[from] tokio::task::JoinError),\n    #[error(\"engine core reported fatal failure\")]\n    EngineCoreDead,\n    #[error(\"startup handshake timed out while waiting for {stage} after {timeout:?}\")]\n    HandshakeTimeout {\n        stage: &'static str,\n        timeout: Duration,\n    },\n    #[error(\"engine input registration timed out after {timeout:?}\")]\n    InputRegistrationTimeout { timeout: Duration },\n    #[error(\"unexpected engine id in startup handshake: expected {expected:?}, got {actual:?}\")]\n    UnexpectedHandshakeIdentity { expected: Vec<u8>, actual: Vec<u8> },\n    #[error(\"unexpected startup handshake message: {message}\")]\n    UnexpectedHandshakeMessage { message: String },\n    #[error(\"unexpected non-control output on coordinator path: {message}\")]\n    UnexpectedCoordinatorOutput { message: String },","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/rust/src/engine-core-client/src/error.rs#L17-L53","documentation":"Error::Transport is the #[from] conversion from zeromq::ZmqError. Every ZMQ socket operation in transport.rs (bind, send, recv, RouterSocket/PullSocket setup) returns ZmqError; the ? operator lifts it into this variant. It means the messaging layer itself failed — connection reset, socket state error, or send/recv failure — not a protocol-level problem.","triggerScenarios":"Any await on a zeromq socket in transport.rs (e.g. handshake_socket.recv(), input_socket.bind(), output sends during streaming) or coordinator socket sends in coordinator/inproc.rs failing at the ZMQ level.","commonSituations":"Engine process died and the ZMQ peer disappeared mid-stream; tcp connections dropped (kill -9 on engine, OOM, container eviction); binding to an address already in use surfaces here too (bind returns ZmqError). Frequent during scale testing when engines are killed intentionally.","solutions":["Check whether the engine processes are still alive (the next likely error is EngineCoreDead after this one)","Retry connect after backing off if the failure happened during startup bind","For 'address in use', pick ephemeral ports (tcp://host:0, which bind_local_sockets does by default) or free the stale socket","Match on the inner ZmqError to distinguish fatal state errors from transient send failures"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"async fn address_bindable(addr: &str) -> bool {\n    zeromq::RouterSocket::new().bind(addr).await.is_ok()\n}","typeGuard":"fn is_transport_error(e: &engine_core_client::Error) -> bool {\n    matches!(e, engine_core_client::Error::Transport(_))\n}","tryCatchPattern":"match result {\n    Err(e @ engine_core_client::Error::Transport(zmq)) => {\n        tracing::warn!(?zmq, \"zmq transient failure; backing off\");\n        tokio::time::sleep(Duration::from_millis(backoff)).await; // retry once; treat repeated failures as fatal\n    }\n    other => other?,\n}","preventionTips":["Use ephemeral ports (tcp://host:0) for handshake-owned sockets to avoid bind collisions","Health-check engines separately so transport errors are distinguishable from engine death","Retry connect with bounded backoff; retry send only when the ZmqError indicates a transient condition"],"tags":["rust","zeromq","network","transport"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}