Pumpkin-MC/Pumpkin · error · ReadingError

incomplete

Error message

incomplete: {0}

What it means

ReadingError::Incomplete signals that a read started successfully but fewer bytes than required were available before the stream ended — the packet is truncated. Unlike CleanEOF (zero bytes available), some bytes arrived, so the peer sent a partially-formed packet or the stream closed mid-packet.

Solutions

  1. Verify the sender computes the packet length field as the exact remaining byte count (id + type + body + null terminators).
  2. Discard the partial packet and close/reconnect; a truncated frame cannot be recovered from a stream.
  3. Add network diagnostics between peers (proxies, load balancers) if truncation recurs.
  4. Log the expected vs actual byte counts to identify which field of which packet truncates.

Example fix

// before: sender writes body but a wrong length prefix
let len = body.len() as i32; // forgot id+type+terminators
stream.write_all(&len.to_be_bytes()).await?;

// after: compute full packet length
let len = (4 + 4 + body.len() + 2) as i32;
stream.write_all(&len.to_be_bytes()).await?;
Defensive patterns

Strategy: try-catch

Validate before calling

// before decoding a framed packet, ensure the full frame is buffered
if buffer.len() < frame_len {
    return Ok(None); // wait for more bytes instead of decoding a partial frame
}

Try / catch

match decode(&mut buf).await {
    Err(ReadingError::Incomplete(exp)) => {
        warn!("truncated packet, expected {exp}; resetting connection");
        connection.close().await;
    }
    other => /* ... */,
}

Prevention

When it happens

Trigger: Reading a field whose declared length exceeds the remaining bytes on the wire, e.g. the packet's length prefix says N bytes but the connection closes after M < N bytes; deserializing a truncated frame from the TCP stream.

Common situations: Network interruption mid-packet (client dropped, proxy cut the connection); a buggy sender computing the length field wrong so the receiver waits for bytes never sent; MTU/proxy issues that chop streams; reading from a socket after the peer aborted.

Related errors


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

Appendix: source

Thrown at crates/pumpkin-protocol/src/ser/mod.rs:23

use crate::{
    FixedBitSet,
    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}")]

View on GitHub (pinned to 8d4639e25a)