Pumpkin-MC/Pumpkin · error · Error

Failed to UTF-8 Decode

Error message

Failed to UTF-8 Decode

What it means

Error::Utf8DecodingError is raised when a string in the NBT payload is not valid UTF-8 (this crate uses this for strings decoded as plain UTF-8, e.g., in Bedrock/network paths). The library throws it because Rust strings must be valid UTF-8 and the raw bytes fail validation. It indicates corrupted data, a wrong length read, or a dialect mismatch.

Solutions

  1. Confirm you are using the decoder variant matching the data (Java CESU-8 strings vs Bedrock UTF-8 strings).
  2. Check the length prefix parsing: Java uses big-endian u16, Bedrock uses a varint — mixing these shifts/cuts strings.
  3. Validate the raw bytes at the reported offset with String::from_utf8 in a test to see the exact failing byte index.
  4. Repair or re-export the source file if the bytes are genuinely corrupted.

Example fix

// before: Java reader applied to Bedrock data
let nbt = Nbt::from_reader(&mut bedrock_stream)?;
// after
let nbt = Nbt::from_reader_bedrock(&mut bedrock_stream)?;
Defensive patterns

Strategy: try-catch

Try / catch

match Nbt::from_reader(&mut reader) {
    Err(pumpkin_nbt::Error::Utf8DecodingError) => eprintln!("invalid UTF-8 string; dialect or corruption issue"),
    Err(e) => return Err(e.into()),
    Ok(nbt) => nbt,
}

Prevention

When it happens

Trigger: A string tag's bytes fail std::str::from_utf8 validation; the length prefix was misread so a multi-byte character is split; reading Java CESU-8 supplementary characters (surrogate 0xED A0-xx sequences) through the strict UTF-8 path; random binary parsed as a string due to offset error.

Common situations: Mixing Java and Bedrock NBT decoders; files truncated mid-string; custom NBT writers that emit non-UTF-8 bytes; desynchronized network streams.

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/d869804b5da71053. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin-nbt/src/lib.rs:83

/// 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}")]
    LargeLength(usize),
    /// A Bedrock variable-length integer exceeded its maximum encoded size.
    #[error("Failed to decode varint - value too large")]

View on GitHub (pinned to 8d4639e25a)