zellij-org/zellij · error
Exceeded log buffer size. Make sure that your plugin calls f
Error message
Exceeded log buffer size. Make sure that your plugin calls flush on stderr on valid UTF-8 symbol boundary. Additionally, make sure that your log message contains endline \n symbol.
What it means
Returned by LoggingPipe::write when a plugin's pending stderr buffer would exceed ZELLIJ_MAX_PIPE_BUFFER_SIZE (16384 bytes). The pipe accumulates bytes and only drains on flush when the buffer forms complete, newline-terminated UTF-8 lines; without newlines the buffer grows until this hard cap trips, the buffer is discarded, and the plugin sees an InvalidData error on stderr.
Source
Thrown at zellij-server/src/logging_pipe.rs:47
"|{:<25.25}| {} [{:<10.15}] {}",
self.plugin_name,
chrono::Local::now().format("%Y-%m-%d %H:%M:%S.%3f"),
format!("id: {}", self.plugin_id),
message
);
}
}
impl Write for LoggingPipe {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
if self.buffer.len() + buf.len() > ZELLIJ_MAX_PIPE_BUFFER_SIZE {
let error_msg =
"Exceeded log buffer size. Make sure that your plugin calls flush on stderr on \
valid UTF-8 symbol boundary. Additionally, make sure that your log message contains \
endline \\n symbol.";
error!("{}: {}", self.plugin_name, error_msg);
self.buffer.clear();
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
error_msg,
));
}
self.buffer.extend(buf);
self.flush()?;
Ok(buf.len())
}
// When we flush, check if current buffer is valid utf8 string, split by '\n' and truncate buffer in the process.
// We assume that eventually, flush will be called on valid string boundary (i.e. std::str::from_utf8(..).is_ok() returns true at some point).
// Above assumption might not be true, in which case we'll have to think about it. Make it simple for now.
fn flush(&mut self) -> std::io::Result<()> {
self.buffer.make_contiguous();
match std::str::from_utf8(self.buffer.as_slices().0) {View on GitHub (pinned to 98a0837077)
Solutions
- End every stderr log line with '\n' (use eprintln! rather than eprint!)
- Flush stderr after each log statement or logical batch
- Chunk or truncate very large messages (e.g. log first 1KiB of a payload) so a single line stays well under 16KiB
- Never write non-UTF-8 or partial multibyte sequences without flushing at character boundaries
Example fix
// before (Rust plugin)
eprint!("long diagnostic without newline: {}", huge_string);
// after
eprintln!("diagnostic: {}", &huge_string[..huge_string.len().min(1024)]); Defensive patterns
Strategy: validation
Validate before calling
const MAX_PIPE_BUFFER: usize = 16_384;
fn stderr_chunk_is_safe(chunk: &[u8], pending: usize) -> bool {
pending + chunk.len() <= MAX_PIPE_BUFFER
&& chunk.ends_with(b"\n")
&& std::str::from_utf8(chunk).is_ok()
} Type guard
fn log_line_is_pipe_safe(line: &str, pending: usize) -> bool {
pending + line.len() + 1 <= 16_384 && line.contains('\n')
} Try / catch
use std::io::Write;
let mut stderr = std::io::stderr();
if let Err(e) = stderr.write_all(msg.as_bytes()) {
if e.kind() == std::io::ErrorKind::InvalidData {
// buffer exceeded: drop the message, keep the plugin alive
log::warn!("dropped oversized log message");
} else { return Err(e); }
} Prevention
- Always terminate log lines with \n (prefer eprintln! over eprint!)
- Flush stderr after each log call or batch; flush on UTF-8 character boundaries
- Cap single log lines well below 16KiB (truncate large payloads before logging)
- Never write binary or partial multibyte sequences to plugin stderr
When it happens
Trigger: A WASM plugin that writes more than 16KiB to stderr without emitting a '\n' (e.g. using print! in a loop, writing partial UTF-8 sequences, or never flushing), so flush() can never split and drain the buffer.
Common situations: Plugins ported from host programs that log giant single-line blobs; eprintln! with embedded '\r' but no '\n'; a plugin panicking and dumping a huge message without newline; plugins writing binary data to stderr.
Related errors
- No plugin found at '{}'
- Plugin is not stored in memory
- failed to load plugin from disk
- This zellij was built without bundled plugins (feature 'disa
AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16).
Data as JSON: /api/errors/24fb0fb2d697c43d.
Report an issue: GitHub.