risingwavelabs/risingwave · error · ValueEncodingError
Invalid variant encoding
Error message
Invalid variant encoding
What it means
ValueEncodingError::InvalidVariantEncoding is thrown when a Variant column's stored bytes cannot be deserialized into a VariantVal. In deserialize_value for DataType::Variant (src/common/src/util/value_encoding/mod.rs:386-389), VariantVal::value_deserialize returns None for malformed payloads and the code raises this error. It signals that the persisted variant bytes are corrupt or written in an incompatible format.
Solutions
- Ensure the payload was serialized with VariantVal::value_serialize from a matching RisingWave version
- Align reader/writer versions to eliminate format skew
- Rewrite the affected rows (re-ingest or refresh the materialization)
- Validate variant payloads before persistence
Example fix
// before let val = VariantVal::value_deserialize(bytes).ok_or(ValueEncodingError::InvalidVariantEncoding)?; // after: check length prefix against actual slice length first let (len, rest) = (u32::from_le_bytes(bytes[..4].try_into().unwrap()) as usize, &bytes[4..]); assert_eq!(len, rest.len(), "truncated variant payload"); let val = VariantVal::value_deserialize(rest).ok_or(ValueEncodingError::InvalidVariantEncoding)?;
Defensive patterns
Strategy: try-catch
Validate before calling
fn valid_variant_payload(bytes: &[u8]) -> bool {
!bytes.is_empty() && VariantVal::value_deserialize(bytes).is_some()
} Type guard
fn is_decodable_variant(bytes: &[u8]) -> Option<VariantVal> {
VariantVal::value_deserialize(bytes)
} Try / catch
match deserialize_datum(&DataType::Variant, data) {
Ok(Some(datum)) => { /* use datum */ }
Ok(None) => { /* NULL datum */ }
Err(ValueEncodingError::InvalidVariantEncoding) => {
tracing::error!("corrupt variant bytes; skip or rewrite row");
}
Err(e) => return Err(e),
} Prevention
- Use VariantVal::value_serialize exclusively for persisting variants
- Verify length prefix matches payload length before decoding
- Add encode/decode round-trip tests for variant columns
- Align RisingWave versions across writer and reader nodes
When it happens
Trigger: Calling deserialize_value/deserialize_datum on DataType::Variant where the length-prefixed bytea payload is not valid variant binary encoding (truncation, foreign writer, format-version mismatch).
Common situations: Reading rows written by a cluster version with a different variant layout; data ingested/persisted by an external tool; corrupted storage bytes; hand-crafted bytes passed to the deserializer in tests.
Related errors
- Invalid jsonb encoding
- Invalid bool value encoding
- Invalid Date value encoding: days
- Invalid flag
- Invalid list encoding
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/869a3da3868fd27b.
Report an issue: GitHub.
Appendix: source
Thrown at src/common/src/util/value_encoding/error.rs:33
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}")]
InvalidVectorItem(f32, String),
}View on GitHub (pinned to 6469eb736d)