python/cpython · error · ValueError
readexactly size can not be less than zero
Error message
readexactly size can not be less than zero
What it means
ValueError raised by StreamReader.readexactly() when n is negative. The function's contract is to return exactly n bytes (or raise IncompleteReadError), which is meaningless for negative n, so it fails fast before checking the buffer.
Source
Thrown at Lib/asyncio/streams.py:752
return data
async def readexactly(self, n):
"""Read exactly `n` bytes.
Raise an IncompleteReadError if EOF is reached before `n` bytes can be
read. The IncompleteReadError.partial attribute of the exception will
contain the partial read bytes.
if n is zero, return empty bytes object.
Returned value is not limited with limit, configured at stream
creation.
If stream was paused, this function will automatically resume it if
needed.
"""
if n < 0:
raise ValueError('readexactly size can not be less than zero')
if self._exception is not None:
raise self._exception
if n == 0:
return b''
while len(self._buffer) < n:
if self._eof:
incomplete = self._buffer.take_bytes()
raise exceptions.IncompleteReadError(incomplete, n)
await self._wait_for_data('readexactly')
data = self._buffer.take_bytes(n)
self._maybe_resume_transport()
return data
View on GitHub (pinned to bc6749cc3b)
Solutions
- Validate n >= 0 before the call and fail with a protocol-framing error if the peer sent a bogus length
- Check your size arithmetic: clamp or assert on intermediate values in the framing loop early (fail fast at parse time)
- Use reader.read(n) for variable-length reads and readexactly only with a validated non-negative count
Example fix
// before
payload = await reader.readexactly(declared_len - header_size) # can go negative
// after
n = declared_len - header_size
if n < 0:
raise ProtocolError(f'bad length: {declared_len}')
payload = await reader.readexactly(n) Defensive patterns
Strategy: validation
Validate before calling
def checked_read_size(n: int) -> int:
if not isinstance(n, int) or n < 0:
raise ValueError(f'readexactly size must be >= 0, got {n!r}')
return n Type guard
null
Try / catch
null
Prevention
- Validate length prefixes from the wire against protocol bounds before framing reads
- Add asserts in framing arithmetic so underflow fails at the source line
When it happens
Trigger: await reader.readexactly(n) where n is a computed length that went negative: size arithmetic like remaining - chunk with unsigned underflow in concept, a parsed header length field with a negative value, or -1 used as a sentinel reaching this call.
Common situations: Protocol parsers reading a length prefix that was validated nowhere; slicing/subtraction mistakes in framing loops; passing a 'read all' sentinel (-1) from a different API into readexactly.
Related errors
- Limit cannot be <= 0
- Separator should contain at least one element
- Separator should be at least one-byte string
- Unimplemented ioctl request
- profiling_trace: Placeholder pattern not found in {js_path.n
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/e081f264cf53eb03.
Report an issue: GitHub.