risingwavelabs/risingwave · error · ValueEncodingError

Invalid jsonb encoding

Error message

Invalid jsonb encoding

What it means

ValueEncodingError::InvalidJsonbEncoding is thrown by RisingWave's value_encoding module when a Jsonb column's stored bytes cannot be deserialized back into a JsonbVal. During deserialize_value for DataType::Jsonb (src/common/src/util/value_encoding/mod.rs:382-385), JsonbVal::value_deserialize returns None on malformed bytes, and the code converts that into this error. It indicates the persisted or transmitted encoding of a jsonb datum is corrupt or was written by an incompatible format version.

Source

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

// limitations under the License.

use thiserror::Error;

#[derive(Error, Debug)]
pub enum ValueEncodingError {
    #[error("Invalid bool value encoding: {0}")]
    InvalidBoolEncoding(u8),
    #[error("Invalid UTF8 value encoding: {0}")]
    InvalidUtf8(#[from] std::string::FromUtf8Error),
    #[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}")]

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify the bytes being decoded were produced by JsonbVal::value_serialize with the same encoding version
  2. Check for version skew between the writer and reader clusters and upgrade/downgrade so both use the same value-encoding format
  3. Re-ingest or re-materialize the affected data to rewrite the jsonb bytes
  4. If it comes from user input, validate jsonb input before persisting

Example fix

// before: decoding untrusted bytes directly
let val = JsonbVal::value_deserialize(bytes).ok_or(ValueEncodingError::InvalidJsonbEncoding)?;
// after: validate the payload round-trips before use
let val = JsonbVal::value_deserialize(bytes)
    .filter(|v| serde_json::to_vec(v.as_scalar_ref().0).is_ok())
    .ok_or_else(|| ValueEncodingError::InvalidJsonbEncoding)?;
Defensive patterns

Strategy: try-catch

Validate before calling

fn valid_jsonb_payload(bytes: &[u8]) -> bool {
    !bytes.is_empty() && JsonbVal::value_deserialize(bytes).is_some()
}

Type guard

fn is_decodable_jsonb(bytes: &[u8]) -> Option<JsonbVal> {
    JsonbVal::value_deserialize(bytes)
}

Try / catch

match deserialize_datum(&DataType::Jsonb, data) {
    Ok(Some(datum)) => { /* use datum */ }
    Ok(None) => { /* NULL datum */ }
    Err(ValueEncodingError::InvalidJsonbEncoding) => {
        tracing::error!("corrupt jsonb bytes; skip or rewrite row");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling deserialize_value/deserialize_datum on DataType::Jsonb where the length-prefixed bytea payload is not valid jsonb binary (truncated data, wrong version writer, or bytes produced by a different serializer).

Common situations: Reading rows written by an older/newer RisingWave version whose jsonb binary layout changed; manual or external writes to storage that bypass the serializer; corrupted state-store bytes; mixing row encodings (memcompatible vs column-aware) when decoding.

Understand the failure class

Related errors


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