vllm-project/vllm · error · Error

messagepack value decode failed

Error message

messagepack value decode failed

What it means

Error::ValueDecode wraps rmpv::decode::Error via #[from]. It is produced when a dynamic MessagePack value read from a byte stream fails at the rmpv layer (malformed MessagePack bytes, truncated frame, bad type marker) before any typed conversion happens.

Source

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

use crate::protocol::utility::UtilityCallId;

pub type Result<T> = std::result::Result<T, Error>;

/// Public error type for the Rust engine-core client.
#[derive(Debug, Error, Macro)]
pub enum Error {
    #[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,
    },

View on GitHub (pinned to c794754062)

Solutions

  1. Log the frame length and first bytes at the failure site to distinguish truncation from corruption
  2. Verify the Python encoder (msgpack) and Rust decoder (rmpv) versions agree on MessagePack spec level
  3. Check frame reassembly logic if custom aux-frame splitting is in play
  4. If reproducible, feed the exact bytes to rmpv::decode::read_value in a test and file the frame dump
Defensive patterns

Strategy: try-catch

Type guard

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

Try / catch

if let Err(engine_core_client::Error::ValueDecode(inner)) = result {
    tracing::error!(?inner, "malformed messagepack frame");
}

Prevention

When it happens

Trigger: Any code path that reads rmpv::Value directly from engine bytes — e.g. dynamic inspection of output payloads or logprobs decoding — where the byte buffer is not valid MessagePack. The From impl converts the raw rmpv error into this variant automatically at ? boundaries.

Common situations: Frames corrupted or truncated in transit, a ZMQ multipart message reassembled with wrong frame boundaries, or a Python-side encoder change emitting a format rmpv rejects. Rare compared to the typed Decode variant; usually indicates genuinely malformed bytes rather than a schema mismatch.

Related errors


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