Pumpkin-MC/Pumpkin · error
slots_len exceeds limit
Error message
slots_len exceeds limit
What it means
Thrown while decoding legacy inventory slots in the Bedrock PlayerAuthInput packet when the declared slots length exceeds 1024. The limit stops untrusted input from forcing huge allocations or long parse loops.
Solutions
- Verify client and server Bedrock protocol versions align
- Check network path for corruption/desync
- Treat repeat offenders as malicious and disconnect them
- Only raise the 1024 limit if a legitimate use case exists
Defensive patterns
Strategy: validation
Validate before calling
let slots_len = VarUInt::read(buf)?.0 as usize;
if slots_len > 1024 { return Err(...); } Try / catch
if let Err(e) = packet.read(&mut reader) {
if e.kind() == std::io::ErrorKind::InvalidData { return disconnect(peer); }
return Err(e.into());
} Prevention
- Validate every length prefix against a protocol constant
- Reserve only min(len, cap) capacity
- Test decoders with hostile length values (usize::MAX encoded)
- Keep protocol version negotiation strict
When it happens
Trigger: PlayerAuthInput with a legacy request id that is < -1 and even, where the subsequent VarUInt slots_len is > 1024.
Common situations: Exploit attempts with inflated length prefixes, protocol version mismatches, or corrupted packet streams.
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
- actions_len exceeds limit
- item string array length out of bounds
- miss_count exceeds limit
- hit_count exceeds limit
- length exceeds
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/cb3c1a9ebb9c2640.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-protocol/src/bedrock/server/player_auth_input.rs:166
}
}
#[derive(Debug)]
pub struct PlayerInventoryAction {
pub legacy_request_id: VarInt,
pub legacy_slots: Vec<crate::bedrock::server::inventory_transaction::LegacySetItemSlot>,
pub actions: Vec<crate::bedrock::server::inventory_transaction::InventoryAction>,
pub transaction: PlayerUseItemTransactionData,
}
impl PacketRead for PlayerInventoryAction {
fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {
let legacy_request_id = VarInt::read(buf)?;
let mut legacy_slots = Vec::new();
if bool::read(buf)? && legacy_request_id.0 < -1 && (legacy_request_id.0 & 1) == 0 {
let slots_len = VarUInt::read(buf)?.0 as usize;
if slots_len > 1024 {
return Err(Error::new(
ErrorKind::InvalidData,
"slots_len exceeds limit",
));
}
legacy_slots.reserve(slots_len.min(64));
for _ in 0..slots_len {
legacy_slots.push(
crate::bedrock::server::inventory_transaction::LegacySetItemSlot::read(buf)?,
);
}
}
let mut actions = Vec::new();
if bool::read(buf)? && bool::read(buf)? {
let actions_len = VarUInt::read(buf)?.0 as usize;
if actions_len > 1024 {
return Err(Error::new(
ErrorKind::InvalidData,
"actions_len exceeds limit",View on GitHub (pinned to 8d4639e25a)