python/cpython · warning · BlockingIOError
EAGAIN
EAGAIN
Error message
write could not complete without blocking
What it means
Raised by BufferedWriter._flush_unlocked when raw.write() returns None — the RawIOBase signal for 'would block' — meaning no bytes could be written right now. The buffer converts that into BlockingIOError(errno.EAGAIN, 'write could not complete without blocking', 0), i.e. a zero-byte partial write, so the caller knows to retry later.
Source
Thrown at Lib/_pyio.py:1317
if pos is None:
pos = self.raw.tell()
return self.raw.truncate(pos)
def flush(self):
with self._write_lock:
self._flush_unlocked()
def _flush_unlocked(self):
if self.closed:
raise ValueError("flush on closed file")
while self._write_buf:
try:
n = self.raw.write(self._write_buf)
except BlockingIOError:
raise RuntimeError("self.raw should implement RawIOBase: it "
"should not raise BlockingIOError")
if n is None:
raise BlockingIOError(
errno.EAGAIN,
"write could not complete without blocking", 0)
if n > len(self._write_buf) or n < 0:
raise OSError("write() returned incorrect number of bytes")
del self._write_buf[:n]
def tell(self):
return _BufferedIOMixin.tell(self) + len(self._write_buf)
def seek(self, pos, whence=0):
if whence not in valid_seek_flags:
raise ValueError("invalid whence value")
with self._write_lock:
self._flush_unlocked()
return _BufferedIOMixin.seek(self, pos, whence)
def close(self):
with self._write_lock:View on GitHub (pinned to bc6749cc3b)
Solutions
- Catch BlockingIOError from flush/write and retry once the fd reports writable (selectors.select for EVENT_WRITE).
- Put the fd back in blocking mode if you cannot implement backpressure.
- Bound the buffered amount yourself (stop writing when pending bytes exceed a watermark) so flush rarely hits EAGAIN.
Example fix
# before
writer.flush() # BlockingIOError on full non-blocking socket
# after
import selectors
sel = selectors.DefaultSelector()
sel.register(sock, selectors.EVENT_WRITE)
while True:
try:
writer.flush()
break
except BlockingIOError:
sel.select() # wait until writable, then retry flush Defensive patterns
Strategy: retry
Validate before calling
import selectors
sel = selectors.DefaultSelector()
sel.register(sock, selectors.EVENT_WRITE)
if not sel.select(0):
... # not writable yet; defer flush
else:
writer.flush() Try / catch
while True:
try:
writer.flush()
break
except BlockingIOError:
sel.select() # wait for EVENT_WRITE, retry Prevention
- Only flush when the selector reports the fd writable.
- Handle characters_written == 0 by backing off and retrying.
- Use blocking fds when no backpressure handling exists.
When it happens
Trigger: Flushing a BufferedWriter over a non-blocking socket/pipe whose send buffer is full (raw.write returns None); flushing after the peer stopped reading; BufferedWriter.seek()/truncate() on a full non-blocking stream (they flush internally).
Common situations: Non-blocking network writers under backpressure; pipe-based producers outrunning consumers; mixing blocking assumptions (assuming flush always completes) with non-blocking fds.
Related errors
- {e.strerror}
- "raw" argument must be writable.
- self.raw should implement RawIOBase: it should not raise Blo
- write() returned incorrect number of bytes
- peek on closed file
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/e439bfe1cd7f6a6b.
Report an issue: GitHub.