OSError raw write returned invalid length when using print in python
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
OSError: raw write() returned invalid length usually means the stream under print() is broken, not that print() itself is wrong. Python expected the underlying raw stream to report the number of bytes it wrote, but the stream returned an impossible value or otherwise violated the file-like object contract.
What print() Writes To
print() ultimately writes text to sys.stdout unless you override the file argument. In a normal terminal, sys.stdout is a TextIOWrapper layered on top of a buffered binary stream and then a raw file descriptor.
If one of those lower layers is replaced with a custom object that implements write() incorrectly, Python can raise this error.
A raw write() method is expected to return:
- the number of bytes written, as an integer
- or
Noneonly in specific non-blocking situations, depending on the layer
Returning an impossible length breaks the contract.
A Minimal Broken Example
The following example intentionally implements a bad raw stream. It reproduces the failure pattern by returning a length larger than the number of bytes received.
The stream claims it wrote more bytes than Python handed to it, so the I/O stack rejects the result.
Where This Happens in Real Code
In production code, the error tends to appear in unusual output environments, such as:
- custom logging or stdout redirection wrappers
- embedded interpreters
- notebook or REPL integrations
- subprocess pipes with incorrect wrappers
- low-level device or socket abstractions pretending to be file objects
The clue is that the problem sits below print(). If print() fails only in one environment and works in a regular terminal, inspect whatever replaced sys.stdout.
Validate the Current Stream
A fast debugging step is to inspect sys.stdout and its underlying buffer objects.
If sys.stdout is a custom proxy or wrapper, look at its write() implementation. That is where the contract is often violated.
Another useful check is to bypass the text wrapper and write directly to stderr or the original stdout to see whether the failure is specific to the replaced stream.
If this works while print() fails, the replacement stdout is the likely culprit.
The Correct Contract for Raw Streams
If you implement a raw writable stream yourself, write() should return the number of bytes actually written.
This version behaves correctly because the raw layer reports exactly how many bytes it accepted.
Watch for Partial Writes and Non-Blocking Behavior
The situation gets more subtle when your stream wraps sockets or non-blocking devices. Partial writes can be legitimate at some layers, but the stream type must support them correctly. If you build a file-like wrapper manually, it is easy to violate the expectations of BufferedWriter or TextIOWrapper.
That is why it is often safer to reuse the standard io abstractions rather than implementing low-level stream behavior from scratch.
When the Error Appears Only With print()
print() adds text encoding, separators, and line endings on top of the text stream. A broken raw layer may not show up until text buffering flushes down to bytes. That can make the error look surprising, because the visible failure is at print() even though the real defect is much lower.
This is also why replacing print() with logging sometimes “fixes” the symptom: the logging handler may write through a different stream.
Common Pitfalls
A common mistake is implementing a custom stream that returns the wrong byte count from write().
Another mistake is replacing sys.stdout with an object that looks file-like at the surface but does not obey the io layer contracts fully.
Developers also forget that text streams and raw byte streams have different responsibilities. Encoding belongs in TextIOWrapper; raw streams should deal in bytes and accurate write counts.
Finally, do not debug this as a formatting bug in print(). The failure is usually in the underlying stream implementation.
Summary
- The error means the raw stream beneath
print()reported an invalid write length. - '
print()is usually not the real problem; the stream implementation is.' - Inspect
sys.stdoutand any custom redirection or wrapper code. - A correct raw
write()must report the number of bytes actually written. - Reuse Python's standard
iostack when possible instead of building low-level stream layers by hand.

