BrokenPipeError: [Errno 32] Broken pipe
Python · updated 2026-11-04
Raised by a write or flush when the reader has closed its end. In a web app it usually means the browser or a proxy disconnected while the response was still streaming. In a script it means stdout was piped into a program such as head that stopped reading.
Traceback (most recent call last):
File "/app/export/stream.py", line 44, in stream_rows
out.write(line)
BrokenPipeError: [Errno 32] Broken pipeQuick fix
In a server, a client disconnect is normal: catch BrokenPipeError around the write, stop producing output and don't report it as an error. In a CLI whose output may be piped into head, follow the Python docs: catch BrokenPipeError at the entry point, point stdout at /dev/null and exit. If it appears on calls to another service, that service closed the connection: treat it like a reset and retry idempotent calls.
- Find what the write was going to: a client response, stdout, a subprocess pipe or another service.
- Client response: catch it, stop the work for that request and log at debug level, not as an error.
- CLI piped into head: catch BrokenPipeError in main, os.dup2 a devnull descriptor onto stdout, then sys.exit(1).
- Subprocess: check whether the child exited early (its exit code and stderr).
- Calls to another service: retry idempotent requests, and make sure a timeout is set.
import os
import sys
def main():
try:
for row in rows():
print(row)
sys.stdout.flush()
except BrokenPipeError:
# The reader (e.g. head) closed early. Silence stdout so the
# interpreter's final flush doesn't raise again, then exit.
devnull = os.open(os.devnull, os.O_WRONLY)
os.dup2(devnull, sys.stdout.fileno())
sys.exit(1)
if __name__ == "__main__":
main()Why it happens
Client disconnected
A user closed the tab, a mobile network dropped, or a proxy hit its timeout while a large or streamed response was being written.
Output piped into a program that stops early
python export.py | head -5: head exits after five lines and the next print fails.
Child process exited
Writing to a subprocess stdin after the child crashed or finished.
Remote service closed the connection
Writing a request body to a server that already closed the socket, for example after a body size limit.
Other fixes
- The Python docs advise against setting SIGPIPE to SIG_DFL to hide this: it makes the program exit without warning whenever any socket closes.
- Group client-disconnect errors separately in your error tracker so real failures stay visible.
Same error, other wording
- BrokenPipeError: [Errno 32] Broken pipe (Exception ignored in flush of stdout)
- ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
- OSError: [Errno 32] Broken pipe
Let your coding agent catch the next one
Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:
> Find the BrokenPipeError errors in production, tell me what the write was going to (a client response, stdout or another service), and handle it the right way for that case instead of reporting every disconnect as an error.
Related errors
- ConnectionResetError: [Errno 104] Connection reset by peer
- RuntimeError: Event loop is closed
- OSError: [Errno 98] Address already in use
More in Network and HTTP
- Error: read ECONNRESETNode.js
- Error: connect ECONNREFUSED 127.0.0.1:5432Node.js
- Error: connect ETIMEDOUT 10.0.4.12:5432Node.js
- TypeError: fetch failedNode.js
- Error: self-signed certificate in certificate chainNode.js
- Error: getaddrinfo ENOTFOUND api.example.comNode.js
- Error: write EPIPENode.js
- Access to fetch at 'https://api.example.com/orders' from origin 'https://app.example.com'...Node.js
- AxiosError: Request failed with status code 401Node.js
- requests.exceptions.ConnectionError: HTTPSConnectionPool(host='api.example.com'...Python
- httpx.ReadTimeout: The read operation timed outPython
- [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer...Python
- Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the clientNode.js
- 422 Unprocessable Entity: {"detail":[{"type":"missing","loc":["body","email"],"msg":"Field...Python
References: Python docs: Note on SIGPIPE, Python docs: built-in exceptions (BrokenPipeError)