risingwavelabs/risingwave · error
cannot decode user key {} into raw bytes
Error message
cannot decode user key {} into raw bytes What it means
print_user_key_in_archive expects the user_key argument to be a hex-encoded byte string that decodes into a Hummock UserKey. If hex decoding fails the command panics, since there is no meaningful way to proceed without the key bytes.
Source
Thrown at src/ctl/src/cmd_impl/hummock/validate_version.rs:73
archive_object_store: ObjectStoreRef,
) -> anyhow::Result<HummockVersionArchive> {
use prost::Message;
let archive_dir = version_archive_dir(data_dir);
let archive_path = format!("{archive_dir}/{archive_id}");
let archive_bytes = archive_object_store.read(&archive_path, ..).await?;
let archive: HummockVersionArchive = HummockVersionArchive::decode(archive_bytes)?;
Ok(archive)
}
pub async fn print_user_key_in_archive(
context: &CtlContext,
archive_ids: impl IntoIterator<Item = HummockVersionId>,
data_dir: String,
user_key: String,
use_new_object_prefix_strategy: bool,
) -> anyhow::Result<()> {
let user_key_bytes = hex::decode(user_key.clone()).unwrap_or_else(|_| {
panic!("cannot decode user key {} into raw bytes", user_key);
});
let user_key = UserKey::decode(&user_key_bytes);
println!("user key: {user_key:?}");
let hummock_opts =
HummockServiceOpts::from_env(Some(data_dir.clone()), use_new_object_prefix_strategy)?;
let hummock = context.hummock_store(hummock_opts).await?;
let sstable_store = hummock.sstable_store();
let archive_object_store = sstable_store.store();
for archive_id in archive_ids.into_iter().sorted() {
println!("search archive {archive_id}");
let archive = get_archive(archive_id, &data_dir, archive_object_store.clone()).await?;
let mut base_version =
HummockVersion::from_persisted_protobuf(archive.version.as_ref().unwrap());
print_user_key_in_version(sstable_store.clone(), &base_version, &user_key).await?;
for delta in &archive.version_deltas {
base_version.apply_version_delta(&HummockVersionDelta::from_persisted_protobuf(delta));
print_user_key_in_version(sstable_store.clone(), &base_version, &user_key).await?;View on GitHub (pinned to 6469eb736d)
Solutions
- Hex-encode the user key before passing it (e.g. `echo -n <bytes> | xxd -p` or using the original hex string from logs)
- Check for accidental whitespace or characters outside [0-9a-fA-F] and even length
- Re-extract the key from the manifest/SST debug output that provides it in hex
Example fix
// before rw hummock print-user-key ... --user-key 'row_id=1' // after rw hummock print-user-key ... --user-key 'fa1e000001'
Defensive patterns
Strategy: validation
Validate before calling
if user_key.len() % 2 != 0 || !user_key.bytes().all(|b| b.is_ascii_hexdigit()) {
panic!("user_key must be a hex string");
} Prevention
- Always copy user keys in hex from the tool/log output
- Encode raw keys with `xxd -p` or equivalent before passing
- Check for even length and hex-only characters
When it happens
Trigger: Passing a user_key argument containing non-hex characters or an odd number of characters, e.g. a raw string instead of its hex encoding.
Common situations: Copying a user key from logs and forgetting to hex-encode (or copying only part of it); passing a human-readable key; shell mangling of the argument.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- error parsing with props json
- Pb decode error: {0}
- Invalid vector item: {0} {1}
- failed to convert JSON schema to Avro schema: {}
- Parquet parser error: {message}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/c57d4c99ebc6ba99.
Report an issue: GitHub.