Pumpkin-MC/Pumpkin · error

JWT length exceeds limit

Error message

JWT length {jwt_len} exceeds limit {MAX_PACKET_DATA_SIZE}

What it means

Thrown when the u32-length-prefixed JWT chain blob inside the Bedrock Login packet declares a length greater than MAX_PACKET_DATA_SIZE. The guard prevents allocating an unbounded buffer from untrusted input. The login is rejected with an InvalidData error before authentication can proceed.

Solutions

  1. Confirm client/server protocol versions match
  2. Inspect the raw login packet to verify the JWT length field value
  3. If a legitimate deployment needs larger tokens, raise MAX_PACKET_DATA_SIZE
  4. Ensure encryption at the raknet layer isn't corrupting the stream
Defensive patterns

Strategy: validation

Validate before calling

fn jwt_len_ok(len: usize) -> bool { len <= MAX_PACKET_DATA_SIZE }

Type guard

fn bounded(len: u32) -> Option<usize> { usize::try_from(len).ok().filter(|&l| l <= MAX_PACKET_DATA_SIZE) }

Try / catch

if let Err(e) = SLogin::read(reader) {
    if e.to_string().contains("JWT length") { drop(peer); return Ok(()); }
    return Err(e.into());
}

Prevention

When it happens

Trigger: A client sends a Login packet with a JWT-length field exceeding MAX_PACKET_DATA_SIZE; occurs with malformed packets, crafted DoS attempts, or a desynchronized stream misinterpreting subsequent bytes as the length.

Common situations: Hostile clients probing the login path, proxy corruption, or protocol drift between client and server changing the expected layout.

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


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

Appendix: source

Thrown at crates/pumpkin-protocol/src/bedrock/server/login.rs:33

    pub raw_token: Vec<u8>,
}

impl PacketRead for SLogin {
    fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
        let protocol_version = i32::read_be(reader)?;
        let connection_request_len = VarUInt::read(reader)?.0 as usize;
        if connection_request_len > MAX_PACKET_DATA_SIZE {
            return Err(Error::new(
                ErrorKind::InvalidData,
                format!(
                    "Connection request length {connection_request_len} exceeds limit {MAX_PACKET_DATA_SIZE}"
                ),
            ));
        }

        let jwt_len = u32::read(reader)? as usize;
        if jwt_len > MAX_PACKET_DATA_SIZE {
            return Err(Error::new(
                ErrorKind::InvalidData,
                format!("JWT length {jwt_len} exceeds limit {MAX_PACKET_DATA_SIZE}"),
            ));
        }
        let mut jwt = vec![0; jwt_len];
        reader.read_exact(&mut jwt)?;

        let raw_token_len = u32::read(reader)? as usize;
        if raw_token_len > MAX_PACKET_DATA_SIZE {
            return Err(Error::new(
                ErrorKind::InvalidData,
                format!("Raw token length {raw_token_len} exceeds limit {MAX_PACKET_DATA_SIZE}"),
            ));
        }
        let mut raw_token = vec![0; raw_token_len];
        reader.read_exact(&mut raw_token)?;

        Ok(Self {

View on GitHub (pinned to 8d4639e25a)