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

  1. Verify the string length prefix was read correctly (unsigned short for Java NBT) — a misread length is the most common cause.
  2. 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.
  3. Scan the bytes for invalid sequences (0xC0 0x80 is valid CESU-8; truncated 0x8x continuation bytes are not) to locate corruption.
  4. 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

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


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)