vllm-project/vllm · error · Error

messagepack encode failed for {target_type}: {message}

Error message

messagepack encode failed for {target_type}: {message}

What it means

A MessagePack serialization failure. The crate encodes every request and handshake message with rmp_serde::to_vec_named (rust/src/engine-core-client/src/protocol/mod.rs:43) and utility-call args with rmpv::ext::to_value (protocol/utility.rs:177); when serialization fails, the error is wrapped as Error::Encode { target_type, message } where target_type names the exact struct being encoded. It means a Rust value could not be represented as MessagePack, typically because a field type or enum shape is not serializable.

Source

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

// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright contributors to the vLLM project

use std::sync::Arc;
use std::time::Duration;

use thiserror::Error;
use thiserror_ext::Macro;

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")]

View on GitHub (pinned to c794754062)

Solutions

  1. Check target_type in the error to find the exact struct, then audit its serde attributes (skip, skip_serializing_if, with)
  2. Reproduce locally: rmp_serde::to_vec_named(&value) in a unit test over the failing request to see the underlying serde message
  3. Align the Rust and Python schema versions if a field type changed on one side only
  4. For new fields, mirror existing patterns: #[serde(default)] plus Option<T>

Example fix

// before
pub mm_features: Option<Vec<MultimodalFeature>>, // inner tensor type lacks Serialize

// after
#[serde(default, skip_serializing_if = "Option::is_none")]
pub mm_features: Option<Vec<MultimodalFeature>>, // MultimodalFeature derives Serialize
Defensive patterns

Strategy: try-catch

Validate before calling

fn can_encode<T: serde::Serialize>(value: &T) -> bool {
    rmp_serde::to_vec_named(value).is_ok()
}

Type guard

fn is_encode_error(e: &engine_core_client::Error) -> bool {
    matches!(e, engine_core_client::Error::Encode { .. })
}

Try / catch

match result {
    Err(e @ engine_core_client::Error::Encode { target_type, .. }) => {
        tracing::warn!(target_type, %e, "request not encodable; dropping");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Encoding an EngineCoreRequest whose payload contains a non-serializable field (e.g. a type with no Serialize impl, a map with non-string keys, or an enum without serde tag attributes), or a HandshakeInitMessage / utility-call args value that fails rmp_serde/rmpv serialization. Raised from encode_msgpack before any bytes hit the wire.

Common situations: Adding a new field to EngineCoreRequest or a multimodal feature struct and forgetting #[serde(with ...)]/skip attributes. Version skew between the Rust frontend and the Python EngineCore after the wire schema changed. Custom types in reasoning_parser_kwargs or structured-output options that serde cannot serialize.

Related errors


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