valeriansaliou/sonic · error · panic
buffer overflow ({}/{} bytes)
Error message
buffer overflow ({}/{} bytes) What it means
The server's channel thread panics when a single incoming line would exceed MAX_LINE_SIZE (BUFFER_SIZE + LINE_END_GAP + 1). Sonic treats this as a client that does not implement back-pressure, so it terminates the connection thread to protect the buffer.
Source
Thrown at server/src/channel/handle.rs:209
}
// Check for buffer overflow.
// NOTE: To avoid a needless read of `MAX_LINE_SIZE` bytes,
// we also ensure there is enough space for the line
// separator. If there isn’t, next loop cycle will abort
// because the line is too long anyway.
let separator_len = char::from(BUFFER_LINE_SEPARATOR).len_utf8();
if (buffer.len() + read.len()) < (MAX_LINE_SIZE - separator_len) {
buffer.extend(read);
} else {
// Do not continue, as there is too much pending data
// in the buffer. Most likely the client does not
// implement a proper back-pressure management system,
// thus we terminate it.
tracing::error!("closing channel thread because of buffer overflow");
panic!(
"buffer overflow ({}/{} bytes)",
buffer.len() + read.len(),
MAX_LINE_SIZE
);
}
}
Err(err) => {
tracing::error!("closing channel thread with traceback: {}", err);
panic!("closing channel");
}
}
}
}
fn ensure_start(&self, mut stream: &TcpStream) -> Result<ChannelMode, ChannelHandleError> {
#[allow(clippy::never_loop)]
loop {View on GitHub (pinned to e6a72da6a5)
Solutions
- Split large data into commands smaller than the server's MAX_LINE_SIZE (~ BUFFER_SIZE + LINE_END_GAP + 1 bytes)
- Chunk large PUSH payloads into multiple commands
- Reduce payload size (truncate/index only the needed text)
- If you control the deployment, raise the buffer size in the server config to fit your largest command
Example fix
// client
// before
conn.send(format!("PUSH collection bucket {}", huge_text)); // > MAX_LINE_SIZE
// after
for chunk in chunk_text(huge_text, MAX_LINE_SIZE) {
conn.send(format!("PUSH collection bucket {}", chunk));
} Defensive patterns
Strategy: validation
Validate before calling
const MAX_LINE_SIZE: usize = /* server BUFFER_SIZE + LINE_END_GAP + 1 */;
if payload.len() > MAX_LINE_SIZE {
// split into chunked commands before sending
} Try / catch
// server-side is a panic; clients should just keep under the limit
// catch the connection close if you drive the socket yourself
match stream.write_all(line.as_bytes()) {
Ok(_) => {},
Err(e) => reconnect(),
} Prevention
- Chunk large PUSH/QUERY payloads below MAX_LINE_SIZE
- Implement back-pressure in custom clients
- Track Sonic's BUFFER_SIZE when upgrading and re-check limits
When it happens
Trigger: A client sends one command/line whose size (buffer.len() + read.len()) exceeds MAX_LINE_SIZE over the TCP channel in handle_stream, e.g. a QUERY/PUSH payload larger than the server buffer without a newline terminator.
Common situations: Bulk-loading very large strings via PUSH; naive clients writing megabytes without chunking; misconfigured proxies concatenating frames; load-testing tools sending oversized lines.
Related errors
- closing channel
- write_buffer for kv must not be zero
- flush_after for kv must be strictly lower than inactive_afte
- max_background_jobs makes max_flushes unneeded, don’t config
- consolidate_after for fst must be strictly lower than inacti
AI-assisted analysis of valeriansaliou/sonic@e6a72da6a5 (2026-09-01).
Data as JSON: /api/errors/04bd2377768c0029.
Report an issue: GitHub.