tokio-rs/tokio · error · io::Error
provided length would overflow after adjustment
Error message
provided length would overflow after adjustment
What it means
Runtime error from `LengthDelimitedCodec::decode_head` (length_delimited.rs:547). After applying `length_adjustment` to the raw length-field value, `checked_add`/`checked_sub` returned `None` — the adjusted payload size overflowed `usize`. It indicates a `length_adjustment` configuration that pushes a representable length out of range.
Source
Thrown at tokio-util/src/codec/length_delimited.rs:547
LengthDelimitedCodecError { _priv: () },
));
}
// The check above ensures there is no overflow
let n = n as usize;
// Adjust `n` with bounds checking
let n = if self.builder.length_adjustment < 0 {
n.checked_sub(-self.builder.length_adjustment as usize)
} else {
n.checked_add(self.builder.length_adjustment as usize)
};
// Error handling
match n {
Some(n) => n,
None => {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"provided length would overflow after adjustment",
));
}
}
};
src.advance(self.builder.get_num_skip());
// Ensure that the buffer has enough space to read the incoming
// payload
src.reserve(n.saturating_sub(src.len()));
Ok(Some(n))
}
fn decode_data(&self, n: usize, src: &mut BytesMut) -> Option<BytesMut> {
// At this point, the buffer has already had the required capacityView on GitHub (pinned to 625954f365)
Solutions
- Re-check `length_adjustment` sign and magnitude against the protocol spec (`Builder::length_adjustment`).
- Cap the wire length with `max_frame_length` so the adjustment cannot overflow.
- Treat this as a configuration bug — fix the codec builder rather than handling it per-frame.
- Print the builder settings (`length_field_len`, `length_field_offset`, `length_adjustment`, `num_skip`) and compare against the peer.
Example fix
// before: wrong-sign adjustment causes overflow on large frames
let codec = LengthDelimitedCodec::builder()
.length_adjustment(-i64::MAX)
.new_codec();
// after: correct adjustment per protocol spec
let codec = LengthDelimitedCodec::builder()
.length_field_length(4)
.length_adjustment(0)
.new_codec(); Defensive patterns
Strategy: validation
Validate before calling
// Sanity-check the adjustment against the length field's representable range let max_field = (1usize << (length_field_len * 8)) - 1; debug_assert!(length_adjustment.abs() as u64 <= max_field as u64, "adjustment can overflow the field");
Type guard
fn is_length_overflow(e: &io::Error) -> bool {
e.kind() == io::ErrorKind::InvalidInput && e.to_string().contains("overflow after adjustment")
} Try / catch
match framed.next().await {
Some(Err(e)) if is_length_overflow(&e) => { /* config bug: fix builder, then close */ return Err(anyhow!("length_adjustment misconfigured: {e}")); }
other => other,
} Prevention
- Treat this as a build-time configuration bug, not a runtime data condition.
- Document the exact `length_adjustment` value next to the codec builder.
- Validate all builder parameters in a unit test against the protocol spec.
When it happens
Trigger: A length-field value that is valid on its own but, after the configured add/subtract of `length_adjustment`, exceeds `usize::MAX` or underflows. Almost always a builder misconfiguration rather than a runtime data condition.
Common situations: Wrong sign on `length_adjustment`; an adjustment value near `usize::MAX`; confusing the semantics of `length_adjustment` (it modifies the field-derived length, not `data.len()`).
Related errors
- frame size too big
- bytes remaining on stream
- failed to write frame to transport
- Unable to decode input as UTF8
- failed to write entire datagram to socket
AI-assisted analysis of tokio-rs/tokio@625954f365 (2026-08-11).
Data as JSON: /api/errors/8454d16ef48f6390.
Report an issue: GitHub.