python/cpython · error · UnsupportedOperation
File or stream is not readable.
Error message
File or stream is not readable.
What it means
Raised by IOBase._checkReadable() as io.UnsupportedOperation when read() (and readlines/peek-style reads) is called on a stream whose readable() returns False — i.e. a stream opened write- or append-only. It is the runtime enforcement of the mode flags the file was opened with.
Source
Thrown at Lib/_pyio.py:448
def _checkSeekable(self, msg=None):
"""Internal: raise UnsupportedOperation if file is not seekable
"""
if not self.seekable():
raise UnsupportedOperation("File or stream is not seekable."
if msg is None else msg)
def readable(self):
"""Return a bool indicating whether object was opened for reading.
If False, read() will raise OSError.
"""
return False
def _checkReadable(self, msg=None):
"""Internal: raise UnsupportedOperation if file is not readable
"""
if not self.readable():
raise UnsupportedOperation("File or stream is not readable."
if msg is None else msg)
def writable(self):
"""Return a bool indicating whether object was opened for writing.
If False, write() and truncate() will raise OSError.
"""
return False
def _checkWritable(self, msg=None):
"""Internal: raise UnsupportedOperation if file is not writable
"""
if not self.writable():
raise UnsupportedOperation("File or stream is not writable."
if msg is None else msg)
@property
def closed(self):View on GitHub (pinned to bc6749cc3b)
Solutions
- Open for read/write with 'r+' or 'w+' if you must read and write the same handle (mind buffering: flush between write and read).
- Verify writes by reopening: close, then open(path, 'rb') and read back.
- Guard with if stream.readable(): before read attempts in generic code.
- Check the mode string you computed — write-only modes are 'w', 'a', 'x' (and their 'b' forms).
Example fix
// before
with open('out.txt', 'w') as f:
f.write(payload)
f.seek(0)
check = f.read() # UnsupportedOperation: not readable
// after
with open('out.txt', 'w') as f:
f.write(payload)
with open('out.txt', 'r') as f:
check = f.read() # reopen for reading Defensive patterns
Strategy: type-guard
Validate before calling
if stream.readable():
data = stream.read(n)
else:
raise ValueError(f'{stream!r} is not open for reading') Type guard
def is_readable(stream) -> bool:
probe = getattr(stream, 'readable', None)
return callable(probe) and probe() Try / catch
import io
try:
data = f.read()
except io.UnsupportedOperation:
# opened 'w'/'a' — reopen for reading if verification was intended
with open(f.name, 'rb') as rf:
data = rf.read() Prevention
- Use 'r+'/'w+' when a workflow legitimately reads and writes one handle; flush between directions.
- Verify written data by reopening the file, not by reading the write-mode handle.
- Assert the computed mode string before open() in mode-building code.
When it happens
Trigger: open('out.txt', 'w').read(); reading from the stdin pipe of a subprocess (p.stdin.read()); calling .read() on a GzipFile opened 'wb'; helper functions that 'verify' by reading back what they just wrote to a write-mode handle.
Common situations: Read-after-write verification on the same handle without reopening; passing a write handle to a logging/tee helper that reads; mode computed wrongly (e.g. 'w' instead of 'r+') so an intended read-write workflow gets a write-only stream.
Related errors
- File or stream is not writable.
- %s.%s() not supported
- File or stream is not seekable.
- invalid mode: %r
- can't have text and binary mode at once
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/00ff4bab9c2e3325.
Report an issue: GitHub.