linera-io/linera-protocol · error · LimitedWriterError
Writer limit exceeded
Error message
Writer limit exceeded
What it means
LimitedWriter wraps a std::io::Write and enforces a hard byte budget: each write checks that written + buf.len() stays within limit, using checked_sub so overflow also fails. Any single write that would cross the limit returns io::Error wrapping LimitedWriterError ('Writer limit exceeded') instead of a partial write, so the whole write is rejected.
Source
Thrown at linera-base/src/limited_writer.rs:35
limit: usize,
written: usize,
}
impl<W: Write> LimitedWriter<W> {
pub fn new(inner: W, limit: usize) -> Self {
Self {
inner,
limit,
written: 0,
}
}
}
impl<W: Write> Write for LimitedWriter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
// Calculate the number of bytes we can write without exceeding the limit.
// Fail if the buffer doesn't fit.
ensure!(
self.limit
.checked_sub(self.written)
.is_some_and(|remaining| buf.len() <= remaining),
io::Error::other(LimitedWriterError)
);
// Forward to the inner writer.
let n = self.inner.write(buf)?;
self.written += n;
Ok(n)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
#[cfg(test)]
mod tests {View on GitHub (pinned to 6c226ddcb3)
Solutions
- Raise the limit passed to LimitedWriter::new to fit the expected worst-case payload
- Reduce the data being written: paginate the query, drop unnecessary fields, or split into multiple capped writes
- Pre-compute the serialized size first and reject early with a clean error instead of failing mid-write
Example fix
// before
let mut w = LimitedWriter::new(&mut out, 1024); // payload is 2 KiB -> error
// after
let bytes = serde_json::to_vec(&value)?;
if bytes.len() > 1024 {
return Err(anyhow::anyhow!("response too large: {}", bytes.len()));
}
out.write_all(&bytes)?; Defensive patterns
Strategy: validation
Validate before calling
// Size the payload before writing through the cap
let bytes = serde_json::to_vec(&response)?;
if bytes.len() > LIMIT {
return Err(anyhow::anyhow!("payload {} B exceeds cap {} B", bytes.len(), LIMIT));
}
writer.write_all(&bytes)?; Try / catch
use linera_base::limited_writer::LimitedWriterError;
match writer.write_all(&buf) {
Ok(()) => Ok(()),
Err(e) if e.get_ref().and_then(|r| r.downcast_ref::<LimitedWriterError>()).is_some() => {
Err(anyhow::anyhow!("response exceeded {LIMIT} byte cap; reduce payload"))
}
Err(e) => Err(e.into()),
} Prevention
- Set the limit from the actual worst-case payload, not a round number guessed later
- Paginate or truncate large query results at the service layer instead of relying on the writer to fail
- Unit-test the cap: assert oversized payloads are rejected with LimitedWriterError, not a partial write
When it happens
Trigger: Serializing a value through a LimitedWriter (e.g. capping a JSON/bcs response payload) where the encoded output exceeds the limit; a single large write chunk crossing the remaining budget even though earlier writes fit.
Common situations: API/GraphQL response caps in linera services where a query returns more data than the configured cap; increasing an object's size (more chains, larger blobs) past a previously sufficient limit; tests using tiny limits (the unit test writes 6 bytes into a limit of 5).
Related errors
- proof too large: {total_bytes} bytes (max {MAX_PROOF_BYTES})
- too many proof nodes: {} (max {})
- owner should be different from spender
- invalid block export configuration: {message}
- Expected an `ExecutionError`. Got: {self:#?}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/c7ef36191c6c17bf.
Report an issue: GitHub.