Pumpkin-MC/Pumpkin · error

VarLong is too big (overflow)

Error message

VarLong is too big (overflow)

What it means

Thrown when decoding a VarLong whose value does not terminate within 10 bytes (shift reaches 64 bits before the continuation bit clears). The library treats this as data corruption/overflow and returns InvalidData rather than wrapping around.

Solutions

  1. Check for upstream decode desync — a mis-sized earlier field shifts all later reads.
  2. Verify protocol versions match between client and server; update pumpkin if the protocol changed.
  3. Capture and dump raw bytes near the failure to confirm the stream position is correct.
  4. If intentionally decoding untrusted data, validate length before reading and close the connection cleanly.
Defensive patterns

Strategy: try-catch

Try / catch

match VarLong::read_decode(&mut reader) {
    Ok(v) => Ok(v),
    Err(e) if e.to_string().contains("too big") => {
        log::warn!("VarLong overflow; dropping connection");
        Err(DecodeError::Desync)
    }
    Err(e) => Err(e.into()),
}

Prevention

When it happens

Trigger: Reading a VarLong with the 0x80 continuation bit still set after 10 groups; stream desync or reading a signed field with an unsigned codec; corrupt/truncated input.

Common situations: Protocol version mismatch shifting field boundaries; malicious or fuzzed packets; a broken intermediary mangling the stream.

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/f78b17f812b9bbcb. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin-protocol/src/codec/var_long.rs:123

    }
}

impl PacketRead for VarLong {
    fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
        let mut val: u64 = 0;
        let mut shift = 0;

        loop {
            let byte = u8::read(reader)?;
            val |= ((byte & 0x7F) as u64) << shift;

            if (byte & 0x80) == 0 {
                break;
            }

            shift += 7;
            if shift >= 64 {
                return Err(Error::new(
                    std::io::ErrorKind::InvalidData,
                    "VarLong is too big (overflow)",
                ));
            }
        }

        let decoded = ((val >> 1) as i64) ^ -((val & 1) as i64);

        Ok(Self(decoded))
    }
}

impl PacketWrite for VarLong {
    fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
        let mut val = ((self.0 << 1) ^ (self.0 >> 63)) as u64;

        while val > 0x7F {
            ((val as u8 & 0x7F) | 0x80).write(writer)?;

View on GitHub (pinned to 8d4639e25a)