python/cpython · error · ValueError

invalid buffer size

Error message

invalid buffer size

What it means

Raised by the BufferedReader constructor when buffer_size is zero or negative. The wrapper requires a strictly positive buffer size; the check runs after mixin init but before any buffering state is set up. ValueError('invalid buffer size').

Source

Thrown at Lib/_pyio.py:1064

    """BufferedReader(raw[, buffer_size])

    A buffer for a readable, sequential BaseRawIO object.

    The constructor creates a BufferedReader for the given readable raw
    stream and buffer_size. If buffer_size is omitted, DEFAULT_BUFFER_SIZE
    is used.
    """

    def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE):
        """Create a new buffered reader using the given readable raw IO object.
        """
        if not raw.readable():
            raise OSError('"raw" argument must be readable.')

        _BufferedIOMixin.__init__(self, raw)
        if buffer_size <= 0:
            raise ValueError("invalid buffer size")
        self.buffer_size = buffer_size
        self._reset_read_buf()
        self._read_lock = Lock()

    def readable(self):
        return self.raw.readable()

    def _reset_read_buf(self):
        self._read_buf = b""
        self._read_pos = 0

    def read(self, size=None):
        """Read size bytes.

        Returns exactly size bytes of data unless the underlying raw IO
        stream reaches EOF or if the call would block in non-blocking
        mode. If size is negative, read until EOF or until read() would
        block.

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Omit buffer_size to use the DEFAULT_BUFFER_SIZE, or pass a positive int (e.g. 64 * 1024).
  2. Validate/normalize config at load time: buffer_size = max(1, configured) or fall back to the default when <= 0.
  3. Fix the arithmetic that produces 0/negative sizes.

Example fix

# before
reader = io.BufferedReader(raw, buffer_size=cfg.bufsize)  # cfg.bufsize == 0

# after
size = cfg.bufsize if cfg.bufsize and cfg.bufsize > 0 else io.DEFAULT_BUFFER_SIZE
reader = io.BufferedReader(raw, buffer_size=size)
Defensive patterns

Strategy: validation

Validate before calling

buffer_size = cfg.bufsize if isinstance(cfg.bufsize, int) and cfg.bufsize > 0 else io.DEFAULT_BUFFER_SIZE
reader = io.BufferedReader(raw, buffer_size=buffer_size)

Type guard

def valid_buffer_size(v) -> bool:
    return isinstance(v, int) and v > 0

Try / catch

try:
    reader = io.BufferedReader(raw, buffer_size=n)
except ValueError:
    reader = io.BufferedReader(raw)  # fall back to default size

Prevention

When it happens

Trigger: io.BufferedReader(raw, 0), io.BufferedReader(raw, -4096), or a computed size that degenerates to 0 (e.g. int(peak_memory / chunk_count) with a bad chunk count).

Common situations: Sizing buffers from configuration where 0 means 'unset' elsewhere; passing a user-tunable that was never validated; unit tests probing boundary values.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/e2502ad1d6aa49c7. Report an issue: GitHub.