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
- Confirm you are using the decoder variant matching the data (Java CESU-8 strings vs Bedrock UTF-8 strings).
- Check the length prefix parsing: Java uses big-endian u16, Bedrock uses a varint — mixing these shifts/cuts strings.
- Validate the raw bytes at the reported offset with String::from_utf8 in a test to see the exact failing byte index.
- 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
- Use the Bedrock reader for little-endian/UTF-8 data and the Java reader for CESU-8 data
- Check for file truncation when many strings fail at once
- Validate raw bytes with String::from_utf8 when debugging a specific string
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
- Failed to Cesu 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/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)