risingwavelabs/risingwave · error · BindingError::Decode
DecodeError {error}
Error message
DecodeError {error} What it means
BindingError::Decode wraps a prost/prost-derived DecodeError produced while decoding protobuf bytes passed from Java into RisingWave internal messages (e.g. StreamChunk, rows, Watch response payloads). Shown as 'DecodeError {error}'. It means the byte payload crossing the JNI boundary is not a valid encoding of the expected protobuf message.
Source
Thrown at src/jni_core/src/lib.rs:98
LazyLock::new(|| tokio::runtime::Runtime::new().unwrap());
#[derive(Error, Debug)]
pub enum BindingError {
#[error("JniError {error}")]
Jni {
#[from]
error: jni::errors::Error,
backtrace: Backtrace,
},
#[error("StorageError {error}")]
Storage {
#[from]
error: anyhow::Error,
backtrace: Backtrace,
},
#[error("DecodeError {error}")]
Decode {
#[from]
error: DecodeError,
backtrace: Backtrace,
},
#[error("StreamChunkArrayError {error}")]
StreamChunkArray {
#[from]
error: ArrayError,
backtrace: Backtrace,
},
}
type Result<T> = std::result::Result<T, BindingError>;
pub fn to_guarded_slice<'array, 'env>(
array: &'array JByteArray<'env>,View on GitHub (pinned to 6469eb736d)
Solutions
- Verify the Java side serializes with the exact same generated protobuf class/version as the native binding was built with
- Dump the failing byte[] length and first bytes to confirm it is the expected wire format (not base64/compressed text)
- Regenerate the Java protobuf stubs from the same .proto files used to build risingwave_jni_core
- If version skew is expected, pin both the JAR and native library to the same RisingWave release
Example fix
// before byte[] bytes = Base64.decode(payload); // DecodeError: invalid wire type binding.next(bytes); // after byte[] bytes = payload.toByteArray(); // raw protobuf bytes from matching generated class binding.next(bytes);
Defensive patterns
Strategy: validation
Validate before calling
// Java, before crossing the boundary
byte[] bytes = protoMsg.toByteArray(); // never base64/compressed text
if (bytes.length == 0) throw new IllegalStateException("empty protobuf payload"); Try / catch
try {
binding.decode(bytes);
} catch (RuntimeException e) {
if (e.getMessage().contains("DecodeError")) {
// schema/version skew: regenerate stubs, verify byte source
}
throw e;
} Prevention
- Generate Java protobuf stubs from the same .proto revision as the native lib
- Pass raw protobuf bytes only — no base64/compression wrappers
- Pin RisingWave JAR and native library to the same release
- Sanity-check payload size/first bytes when debugging
When it happens
Trigger: Calling JNI entry points that accept serialized protobuf payloads (byte[] containing StreamChunk, row encodings, etc.) where the bytes are truncated, corrupted, produced by a different schema version, or not protobuf at all.
Common situations: Java client built against an older protobuf schema than the native library (version skew); passing compressed or base64 text where raw protobuf bytes are expected; manually assembled byte arrays with wrong field ordering.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- Pb decode error: {0}
- decode pk-index sink position-delete merger metadata
- Pb decode error: {0}
- Decode error: {0}
- Failed to decode prost: field not found `{}`
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/9a9e59154f97818c.
Report an issue: GitHub.