Pumpkin-MC/Pumpkin · error
item string array length out of bounds
Error message
item string array length out of bounds
What it means
This error is thrown while decoding an ItemComponentPacket's user data from a Bedrock client. The packet contains two string arrays (place_on_blocks and destroy_blocks), each prefixed with an i32 count. The library rejects any declared count below 0 or above 1024 because a hostile or malformed count would otherwise cause enormous allocations or long decode loops.
Solutions
- Verify the client and server protocol versions match; a desync shifts field boundaries and corrupts the length field.
- Check the sending mod/client code that builds the item user data to ensure it writes correct array counts.
- Capture and inspect the raw packet payload to confirm whether the bytes are misaligned or genuinely out of range.
- If the value is genuinely large, reduce the number of place_on_blocks/destroy_blocks entries sent (limit is 1024).
Example fix
// before: sending arbitrary-length arrays let place_on: Vec<String> = load_all_blocks(); // may exceed 1024 // after let place_on: Vec<String> = load_all_blocks().into_iter().take(1024).collect();
Defensive patterns
Strategy: validation
Validate before calling
fn validate_string_array_len(len: i32) -> Result<(), String> {
if !(0..=1024).contains(&len) {
return Err(format!("array length {len} out of range 0..=1024"));
}
Ok(())
} Try / catch
match packet_result {
Err(e) if e.to_string().contains("out of bounds") => {
log::warn!("dropping malformed item packet: {e}");
// disconnect or ignore peer
}
other => other?,
} Prevention
- Cap array sizes on the sender side before serialization
- Validate protocol versions between client and server
- Log raw packet bytes for any decode failure to detect desync early
When it happens
Trigger: Triggered by ItemComponentPacket::read -> read_user_data when the i32 array length field for place_on_blocks or destroy_blocks parses to a negative value or a value greater than 1024.
Common situations: Malicious or corrupted packets from untrusted clients, protocol version mismatches where the client serializes the array differently, desynchronized stream parsing that reads garbage bytes as the length field.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- user_data_len exceeds 1MB limit
- extra_data_len exceeds 1MB limit
- Invalid ContainerName ID
- String::from_utf8 error
- Nbt read error
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/94894ed81e2f9e17.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-protocol/src/bedrock/network_item.rs:569
}
}
fn write_user_data_strings<W: Write>(writer: &mut W, values: &[String]) -> Result<(), Error> {
(values.len() as i32).write(writer)?;
for value in values {
let bytes = value.as_bytes();
let len = u16::try_from(bytes.len())
.map_err(|_| Error::new(std::io::ErrorKind::InvalidInput, "item string too long"))?;
writer.write_all(&len.to_be_bytes())?;
writer.write_all(bytes)?;
}
Ok(())
}
fn read_user_data_strings<R: Read>(reader: &mut R) -> Result<Vec<String>, Error> {
let len = i32::read(reader)?;
if !(0..=1024).contains(&len) {
return Err(Error::new(
std::io::ErrorKind::InvalidData,
"item string array length out of bounds",
));
}
let mut values = Vec::with_capacity((len as usize).min(32));
for _ in 0..len {
let mut length = [0; 2];
reader.read_exact(&mut length)?;
let str_len = usize::from(u16::from_be_bytes(length));
if str_len > 32767 {
return Err(Error::new(
std::io::ErrorKind::InvalidData,
"item string too long",
));
}
let mut bytes = vec![0; str_len];
reader.read_exact(&mut bytes)?;
values.push(View on GitHub (pinned to 8d4639e25a)