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
- Verify the sender computes the packet length field as the exact remaining byte count (id + type + body + null terminators).
- Discard the partial packet and close/reconnect; a truncated frame cannot be recovered from a stream.
- Add network diagnostics between peers (proxies, load balancers) if truncation recurs.
- 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
- Compute packet length fields to include id + type + body + trailing nulls exactly.
- Buffer the complete frame before deserializing rather than streaming field-by-field.
- Check proxies/load balancers for idle timeouts that cut connections mid-packet.
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
- EOF, Tried to read but No bytes left to consume
- IO error
- IO error
- JSON error
- Authentication servers are down
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)