vllm-project/vllm · error · Error

transport error

Error message

transport error

What it means

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.

Source

Thrown at rust/src/engine-core-client/src/error.rs:35

    #[error("messagepack encode failed for {target_type}: {message}")]
    Encode {
        target_type: &'static str,
        message: String,
    },
    #[error("messagepack decode failed for {target_type}: {message}")]
    Decode {
        target_type: &'static str,
        message: String,
    },
    #[error("messagepack value decode failed")]
    ValueDecode(#[from] rmpv::decode::Error),
    #[error("messagepack ext value decode failed: {message}")]
    ExtValueDecode { message: String },
    #[error("invalid structured outputs params: {message}")]
    InvalidStructuredOutputsParams { message: String },
    #[error("io error")]
    Io(#[from] std::io::Error),
    #[error("transport error")]
    Transport(#[from] zeromq::ZmqError),
    #[error("ZMQ runtime task failed")]
    ZmqRuntimeTask(#[from] tokio::task::JoinError),
    #[error("engine core reported fatal failure")]
    EngineCoreDead,
    #[error("startup handshake timed out while waiting for {stage} after {timeout:?}")]
    HandshakeTimeout {
        stage: &'static str,
        timeout: Duration,
    },
    #[error("engine input registration timed out after {timeout:?}")]
    InputRegistrationTimeout { timeout: Duration },
    #[error("unexpected engine id in startup handshake: expected {expected:?}, got {actual:?}")]
    UnexpectedHandshakeIdentity { expected: Vec<u8>, actual: Vec<u8> },
    #[error("unexpected startup handshake message: {message}")]
    UnexpectedHandshakeMessage { message: String },
    #[error("unexpected non-control output on coordinator path: {message}")]
    UnexpectedCoordinatorOutput { message: String },

View on GitHub (pinned to c794754062)

Solutions

  1. Check whether the engine processes are still alive (the next likely error is EngineCoreDead after this one)
  2. Retry connect after backing off if the failure happened during startup bind
  3. For 'address in use', pick ephemeral ports (tcp://host:0, which bind_local_sockets does by default) or free the stale socket
  4. Match on the inner ZmqError to distinguish fatal state errors from transient send failures
Defensive patterns

Strategy: retry

Validate before calling

async fn address_bindable(addr: &str) -> bool {
    zeromq::RouterSocket::new().bind(addr).await.is_ok()
}

Type guard

fn is_transport_error(e: &engine_core_client::Error) -> bool {
    matches!(e, engine_core_client::Error::Transport(_))
}

Try / catch

match result {
    Err(e @ engine_core_client::Error::Transport(zmq)) => {
        tracing::warn!(?zmq, "zmq transient failure; backing off");
        tokio::time::sleep(Duration::from_millis(backoff)).await; // retry once; treat repeated failures as fatal
    }
    other => other?,
}

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/89afb89c687f58b9. Report an issue: GitHub.