Broken pipe, explained and fixed
java.io.IOException: Broken pipe is raised when a program writes to a socket (or a pipe) whose other end has already closed. The writing side did nothing inherently wrong; the reader left. In web servers this is a daily, usually harmless event: a user closed the tab, a phone lost signal, or a client timed out mid-download, and the server only discovered it when it tried to write the next chunk of the response. It becomes a real problem when the other end is a service that should not be leaving, or when it appears often enough to point at timeouts set too aggressively somewhere in the chain.
Judge it before fixing anything
- Who is the other end? If the broken pipe appears in a web server's log alongside normal traffic, it is client disconnects: browsers closing, mobile networks dropping, load-balancer health checks that hang up early. Occasional entries are noise, not incidents.
- How often and when? Spikes at a specific response size or duration point at a proxy or load balancer with a shorter timeout than the server's response time: the intermediary closes the connection while the server is still composing the answer.
- What was being written? Large downloads, streaming responses, and report exports are the usual victims, because they hold the connection open long enough for the other side to change its mind.
The responses, matched to the finding
- For client disconnects, log it quietly: catch the exception at the response-writing layer and log at debug or info level without a stack trace; frameworks differ, but the goal is the same, one line, not a page of trace, and no error response attempted on a connection that no longer exists.
- For timeout mismatches, align the chain: compare the timeouts of the client, load balancer, reverse proxy, and application server; the shortest one wins and should be raised above the longest legitimate response time, or the response should be made faster or asynchronous.
- For service-to-service pipes, check the peer's health: a downstream that restarts, runs out of memory, or closes idle connections aggressively will produce broken pipes upstream; its logs at the same timestamps show why it left.
- Avoid retrying the write blindly: for non-idempotent operations a retry after a broken pipe can duplicate effects, the request may have been processed. Buffer small responses fully before writing when correctness matters.
Common questions
Is a broken pipe a bug in my code? Usually it is a fact about the network being reported through your code. It becomes a code concern when it is mishandled (full stack traces for routine disconnects, error responses written to dead connections) or when its frequency signals a timeout problem.
Why does it mention “pipe” for a network connection? The name is inherited from Unix, where the same error (EPIPE) applies to inter-process pipes and sockets alike. The JVM keeps the operating system's wording.
Can it corrupt the data being sent? The write fails partway, so the receiver holds a truncated response and knows it (the connection closed abnormally). Nothing is silently corrupted; the receiver sees an incomplete transfer and can retry the request if it is safe to repeat.
Related errors