Pumpkin-MC/Pumpkin · warning · ReadingError
too large
Error message
too large: {0} What it means
ReadingError::TooLarge is raised when a decoded size exceeds a configured limit — typically a length prefix (string length, array length, or packet length) that would require reading more data than allowed. It protects the server from malicious or corrupt length fields that would cause huge allocations or memory-exhaustion DoS.
Solutions
- Check that the peer speaks the expected protocol version so fields do not desync.
- Verify the configured size limits are appropriate for your deployment (raise only with capacity planning).
- Inspect the offending packet bytes; a huge length from an unknown sender usually means attack or desync — drop the connection.
- Ensure compression/encryption state matches the negotiated protocol stage, which otherwise misaligns the stream.
Example fix
// before: no sanity check before trusting the length
let len = read_var_int(stream).await?;
let mut buf = vec![0u8; len as usize];
// after: enforce a cap
let len = read_var_int(stream).await?;
if len as usize > MAX_PACKET_SIZE {
return Err(ReadingError::TooLarge(format!("packet len {len}")));
}
let mut buf = vec![0u8; len as usize]; Defensive patterns
Strategy: validation
Validate before calling
// enforce limits before reading sized data
const MAX_STRING: i32 = 262_144;
let len = read_var_int(&mut r).await?;
if !(0..=MAX_STRING).contains(&len) {
return Err(ReadingError::TooLarge(format!("string len {len}")));
} Try / catch
match decode(&mut r).await {
Err(ReadingError::TooLarge(what)) => {
warn!("oversized {what}; possible malicious client — dropping");
connection.close().await;
}
other => /* ... */,
} Prevention
- Keep protocol size limits enabled in production; never disable them for convenience.
- Sanity-check that negotiated compression/encryption matches the connection stage to avoid stream desync.
- Rate-limit or ban sources that repeatedly send oversized length prefixes.
When it happens
Trigger: Deserializing a packet whose VarInt or fixed length prefix (e.g. string length, NBT/array size, or the packet frame length itself) exceeds the maximum permitted size enforced by the reader.
Common situations: A malicious client sending a forged length prefix to force the server to allocate gigabytes; deserializing garbage as a length field after stream desync; a protocol-version mismatch where field layouts differ and a non-length byte is read as a length.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- {0}
- Signature verification failed
- Invalid slot
- Player ' ' tried to interact with a closed container
- Multiple players dragging in a container at once
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/a40b39418110fd20.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-protocol/src/ser/mod.rs:25
codec::{
bit_set::BitSet, var_int::VarInt, var_long::VarLong, var_uint::VarUInt, var_ulong::VarULong,
},
};
use pumpkin_nbt::{
compound::NbtCompound, deserializer::NbtReadHelper, serializer::NbtWriteHelperJava, tag::NbtTag,
};
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::{text::TextComponent, version::JavaMinecraftVersion};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ReadingError {
#[error("EOF, Tried to read {0} but No bytes left to consume")]
CleanEOF(String),
#[error("incomplete: {0}")]
Incomplete(String),
#[error("too large: {0}")]
TooLarge(String),
#[error("{0}")]
Message(String),
}
impl serde::de::Error for ReadingError {
fn custom<T: std::fmt::Display>(msg: T) -> Self {
Self::Message(msg.to_string())
}
}
#[derive(Debug, Error)]
pub enum WritingError {
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Serde failure: {0}")]
Serde(String),
#[error("Packet is not supported in Minecraft version {0:?}")]View on GitHub (pinned to 8d4639e25a)