risingwavelabs/risingwave · error · ValueEncodingError

Invalid list encoding: {0}

Error message

Invalid list encoding: {0}

What it means

ValueEncodingError::InvalidListEncoding wraps a crate::array::ArrayError and is raised when deserializing a List (array) datum fails. deserialize_list (src/common/src/util/value_encoding/mod.rs:407+) reads the u32_le length prefix and decodes each element with the list's element type; failures decoding the element data (including ArrayError from building the ListArray) surface as this variant. The wrapped source identifies the failing element decode.

Source

Thrown at src/common/src/util/value_encoding/error.rs:41

    #[error("Invalid Date value encoding: days: {0}")]
    InvalidDateEncoding(i32),
    #[error("invalid Timestamp value encoding: secs: {0} nsecs: {1}")]
    InvalidTimestampEncoding(i64, u32),
    #[error("invalid Time value encoding: secs: {0} nano: {1}")]
    InvalidTimeEncoding(u32, u32),
    #[error("Invalid null tag value encoding: {0}")]
    InvalidTagEncoding(u8),
    #[error("Invalid jsonb encoding")]
    InvalidJsonbEncoding,
    #[error("Invalid variant encoding")]
    InvalidVariantEncoding,
    #[error("Invalid struct encoding: {0}")]
    InvalidStructEncoding(
        #[source]
        #[backtrace]
        crate::array::ArrayError,
    ),
    #[error("Invalid list encoding: {0}")]
    InvalidListEncoding(
        #[source]
        #[backtrace]
        crate::array::ArrayError,
    ),
    #[error("Invalid flag: {0:b}")]
    InvalidFlag(u8),
    #[error("Invalid vector item: {0} {1}")]
    InvalidVectorItem(f32, String),
}

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Check the wrapped ArrayError to identify the failing element decode
  2. Verify the reader's ListType element type matches the writer's
  3. Validate the u32 length prefix against the remaining buffer before decoding
  4. Re-ingest or rewrite rows whose list bytes are corrupt

Example fix

// before
let len = data.get_u32_le() as usize;
for _ in 0..len { inner_deserialize_datum(data, elem_type)?; }
// after: guard the length prefix against remaining bytes
let len = data.get_u32_le() as usize;
if len > data.remaining() { return Err(ValueEncodingError::InvalidListEncoding(/* ArrayError for truncated payload */)); }
Defensive patterns

Strategy: validation

Validate before calling

fn list_len_valid(data: &impl Buf) -> bool {
    // peek the u32_le length prefix without consuming
    let head = &data.chunk()[..4.min(data.chunk().len())];
    head.len() == 4 && u32::from_le_bytes(head.try_into().unwrap()) as usize <= data.remaining()
}

Type guard

fn is_decodable_list(data: &impl Buf) -> bool {
    data.remaining() >= 4 && {
        let mut peek = data;
        let n = peek.get_u32_le() as usize;
        n <= peek.remaining()
    }
}

Try / catch

match deserialize_datum(&DataType::List(list_type), data) {
    Ok(v) => { /* use value */ }
    Err(ValueEncodingError::InvalidListEncoding(src)) => {
        tracing::error!("list element decode failed: {src}");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Decoding DataType::List where the length prefix exceeds remaining bytes, elements were written with a different element type, or element bytes are truncated/corrupt.

Common situations: Element type changed for a list column between writer and reader; truncated payloads from storage corruption; version skew in list encoding layout; test fixtures with hand-built bytes.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/19592e7e04badd10. Report an issue: GitHub.