Pumpkin-MC/Pumpkin · error · Error
Failed to Cesu 8 Decode
Error message
Failed to Cesu 8 Decode
What it means
Error::Cesu8DecodingError is raised when a string payload in the NBT data cannot be decoded as Java CESU-8 (the modified UTF-8 Minecraft/Java uses, where U+0000 is encoded as 0xC0 0x80 and supplementary characters as surrogate pairs). The library throws it because the byte sequence violates CESU-8 encoding rules and cannot be converted losslessly.
Solutions
- Verify the string length prefix was read correctly (unsigned short for Java NBT) — a misread length is the most common cause.
- Check the producing tool: if it writes standard UTF-8 rather than Java modified UTF-8, convert/normalize the data or use a decoder variant that accepts UTF-8.
- Scan the bytes for invalid sequences (0xC0 0x80 is valid CESU-8; truncated 0x8x continuation bytes are not) to locate corruption.
- If the source is external, transcode strings to CESU-8 before embedding them in NBT.
Example fix
// before: writing plain Rust strings via a generic UTF-8 writer writer.write_str(s)?; // standard UTF-8, supplementary chars not surrogate-paired // after: encode as Java modified UTF-8 let cesu = to_java_modified_utf8(s); writer.write_str(&cesu)?;
Defensive patterns
Strategy: try-catch
Try / catch
match Nbt::from_reader(&mut reader) {
Err(pumpkin_nbt::Error::Cesu8DecodingError) => eprintln!("non-CESU-8 string in NBT; check the writer"),
Err(e) => return Err(e.into()),
Ok(nbt) => nbt,
} Prevention
- Ensure tools writing your NBT encode strings as Java modified UTF-8 (CESU-8)
- Verify string length prefixes are read as big-endian u16 for Java NBT
- Round-trip a known file as a regression test for your encode/decode path
When it happens
Trigger: Decoding an NBT string tag whose length-prefixed bytes are not valid CESU-8 (e.g., truncated multi-byte sequence, lone surrogate, or standard UTF-8-encoded supplementary character from a non-Java writer); a length prefix that cuts a character in half due to stream misalignment.
Common situations: Data written by non-Java NBT libraries that emit standard UTF-8 instead of Java's modified UTF-8; corrupted files where a string length was misread; network data desynchronized so the length covers only part of a string.
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
- Failed to UTF-8 Decode
- The root tag of the NBT file is not a compound tag…
- Encountered an unknown NBT tag id
- Serde error
- NBT doesn't support this type
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/7a0bbdaabc25dccc.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-nbt/src/lib.rs:80
/// Numeric identifier for a long-array tag.
pub const LONG_ARRAY_ID: u8 = 0x0C;
/// Maximum number of elements accepted when decoding a list or array.
pub const MAX_ARRAY_LENGTH: usize = 512_000;
/// Maximum nesting depth allowed when decoding NBT compound or list tags.
pub const MAX_NBT_DEPTH: usize = 512;
/// Errors produced while reading, writing, or converting NBT data.
#[derive(Error, Debug)]
pub enum Error {
/// The root tag was not a compound tag and contains the reported tag ID.
#[error("The root tag of the NBT file is not a compound tag. Received tag id: {0}")]
NoRootCompound(u8),
/// A tag ID not defined by the NBT format was encountered.
#[error("Encountered an unknown NBT tag id: {0}.")]
UnknownTagId(u8),
/// A Java CESU-8 string could not be decoded.
#[error("Failed to Cesu 8 Decode")]
Cesu8DecodingError,
/// A string could not be decoded as UTF-8.
#[error("Failed to UTF-8 Decode")]
Utf8DecodingError,
/// Serde reported an invalid value or serializer state.
#[error("Serde error: {0}")]
SerdeError(String),
/// The requested Rust type has no NBT representation.
#[error("NBT doesn't support this type: {0}")]
UnsupportedType(String),
/// The underlying reader or writer returned an I/O error.
#[error("NBT reading was cut short: {0}")]
Incomplete(io::Error),
/// A list or array declared a negative element count.
#[error("Negative list length: {0}")]
NegativeLength(i32),
/// A string, list, or array exceeded the supported length.
#[error("Length too large: {0}")]View on GitHub (pinned to 8d4639e25a)