Pumpkin-MC/Pumpkin · warning

String length exceeds maximum of

Error message

String length {len} exceeds maximum of {MAX_STRING_LENGTH}

What it means

This error is thrown by the `PacketRead for String` deserializer in pumpkin-protocol when a string's length prefix (read as a VarUInt) exceeds MAX_STRING_LENGTH (32767). The limit protects against malformed or hostile packets causing huge allocations. It means the incoming packet's length prefix was too large to be a legitimate string.

Solutions

  1. Verify the sender/protocol version matches the deserializer's expectations
  2. Check for stream desync: log the byte offset and confirm the VarUInt position
  3. Validate/limit input at a higher layer and drop the offending packet/connection
  4. Inspect raw bytes at the read offset to confirm the length prefix is genuine

Example fix

// before
let name: String = packet.read()?; // panics/errs on oversized len
// after
match String::read(&mut reader) {
    Ok(s) => s,
    Err(e) => { log::warn!("bad packet: {e}"); drop_connection(); return; }
}
Defensive patterns

Strategy: validation

Validate before calling

// peek the VarUInt before trusting it
let (len, _) = VarUInt::peek(reader)?;
if len > 32767 { return Err(PacketError::OversizedString(len)); }

Type guard

fn is_valid_string_len(len: usize) -> bool { len <= 32767 }

Prevention

When it happens

Trigger: Deserializing a packet whose String field declares a length prefix > 32767 via <String as PacketRead>::read — e.g. corrupted data, desynced stream, or malicious client.

Common situations: A malicious/corrupted client sends an oversized string length; a packet stream desync (wrong VarUInt parse) makes a random byte sequence get read as a length; protocol version mismatch reinterprets fields.

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


AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/6762dfe594f09f04. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin-protocol/src/serial/deserializer.rs:159

                        }
                    }
                    return Err(err);
                }
            }
        }
        // SAFETY: All N elements were successfully initialized in the loop above.
        Ok(buf.map(|elem| unsafe { elem.assume_init() }))
    }
}

impl PacketRead for String {
    fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
        const MAX_STRING_LENGTH: usize = 32767;

        let len = VarUInt::read(reader)?.0 as usize;

        if len > MAX_STRING_LENGTH {
            return Err(Error::new(
                ErrorKind::InvalidData,
                format!("String length {len} exceeds maximum of {MAX_STRING_LENGTH}"),
            ));
        }

        let mut buf = vec![0u8; len];
        reader.read_exact(&mut buf)?;

        Self::from_utf8(buf)
            .map_err(|_| Error::new(ErrorKind::InvalidData, "Invalid UTF-8 sequence"))
    }
}

impl<T: PacketRead> PacketRead for Vec<T> {
    fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
        let len = VarUInt::read(reader)?.0 as usize;
        if len > 65536 {
            return Err(Error::new(

View on GitHub (pinned to 8d4639e25a)