rust-lang/cargo · error · io::Error
maximum limit reached when reading
Error message
maximum limit reached when reading
What it means
`LimitErrorReader` wraps an inner reader with `take(limit)`, capping total bytes read. On each `read`, if the underlying read returns `Ok(0)` AND the remaining limit has hit `0` (`self.inner.limit() == 0`), the reader returns an `io::Error` (kind `Other`, message `"maximum limit reached when reading"`) instead of a clean EOF. This converts a silent truncation into an explicit error so callers cannot mistake a size-limited stream for a complete one.
Solutions
- Increase the configured read limit if the input is legitimately large and trusted.
- Verify the upstream source is not returning an unexpectedly large or malicious payload.
- Ensure the stream is not being read twice or chained in a way that double-counts bytes against the limit.
Example fix
// before
let mut r = LimitErrorReader::new(source, 1024 * 1024);
// reading >1MiB -> Err("maximum limit reached when reading")
// after
let mut r = LimitErrorReader::new(source, 64 * 1024 * 1024); Defensive patterns
Strategy: try-catch
Validate before calling
// before wrapping, confirm the expected size is within the budget
fn within_budget(expected: u64, limit: u64) -> Result<(), String> {
if expected > limit { return Err(format!("expected {expected} exceeds limit {limit}")); }
Ok(())
} Try / catch
match reader.read_to_end(&mut buf) {
Ok(n) => { /* complete read within limit */ }
Err(e) if e.to_string().contains("maximum limit reached when reading") => {
// handle truncated/oversized input: raise the limit or reject the source
}
Err(e) => return Err(e.into()),
} Prevention
- Size the LimitErrorReader budget to the largest legitimate input.
- Validate Content-Length / expected size before streaming when possible.
- Treat a limit hit as a security/trust signal for untrusted sources.
When it happens
Trigger: Reading from a `LimitErrorReader` past its configured byte budget: the inner `take(limit)` exhausts the limit, the next `read` yields `Ok(0)`, and `limit() == 0` — so the reader signals the cap as an error rather than EOF.
Common situations: Parsing a downloaded file (e.g. crate `.crate` archive, registry index, lockfile) where Cargo imposes a size guard against pathologically large inputs; an upstream server returning a payload larger than the configured cap; or a corrupted/truncated download that exceeds an expected bound.
Related errors
- failed to read path
- path at ` ` was not valid utf-8
- unable to read .cargo-ok file at
- argument for --color must be auto, always, or never, but…
- argument for --color must be auto, always, or never, but…
AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11).
Data as JSON: /api/errors/1cc3e2f3ac1f6e03.
Report an issue: GitHub.
Appendix: source
Thrown at src/util/io.rs:19
use std::io::{self, Read, Take};
#[derive(Debug)]
pub struct LimitErrorReader<R> {
inner: Take<R>,
}
impl<R: Read> LimitErrorReader<R> {
pub fn new(r: R, limit: u64) -> LimitErrorReader<R> {
LimitErrorReader {
inner: r.take(limit),
}
}
}
impl<R: Read> Read for LimitErrorReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.inner.read(buf) {
Ok(0) if self.inner.limit() == 0 => Err(io::Error::new(
io::ErrorKind::Other,
"maximum limit reached when reading",
)),
e => e,
}
}
}
#[cfg(test)]
mod tests {
use super::LimitErrorReader;
use std::io::Read;
#[test]
fn under_the_limit() {
let buf = &[1; 7][..];
let mut r = LimitErrorReader::new(buf, 8);View on GitHub (pinned to eb98b54bc9)