What is causing this WildFly / Undertow broken pipe error?

Rosswerks picture Rosswerks · Sep 26, 2014 · Viewed 10.3k times · Source

I keep getting the following error on a seemingly random basis from a WildFly 8.1.0.Final install running under NetBeans:

08:51:09,742 ERROR [io.undertow.request] (default task-40) Blocking request failed   HttpServerExchange{ GET /web/faces/javax.faces.resource/dynamiccontent.properties}:   java.lang.RuntimeException: java.io.IOException: Broken pipe
at io.undertow.servlet.spec.HttpServletResponseImpl.responseDone(HttpServletResponseImpl.java:527)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:287)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:177)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:727)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_20]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_20]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_20]
Caused by: java.io.IOException: Broken pipe
at sun.nio.ch.FileDispatcherImpl.write0(Native Method) [rt.jar:1.8.0_20]
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) [rt.jar:1.8.0_20]
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) [rt.jar:1.8.0_20]
at sun.nio.ch.IOUtil.write(IOUtil.java:65) [rt.jar:1.8.0_20]
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:470) [rt.jar:1.8.0_20]
at org.xnio.nio.NioSocketConduit.write(NioSocketConduit.java:150) [xnio-nio-3.2.2.Final.jar:3.2.2.Final]
at io.undertow.server.protocol.http.HttpResponseConduit.write(HttpResponseConduit.java:531)
at io.undertow.conduits.ChunkedStreamSinkConduit.flush(ChunkedStreamSinkConduit.java:256)
at org.xnio.conduits.ConduitStreamSinkChannel.flush(ConduitStreamSinkChannel.java:162) [xnio-api-3.2.2.Final.jar:3.2.2.Final]
at io.undertow.channels.DetachableStreamSinkChannel.flush(DetachableStreamSinkChannel.java:100)
at org.xnio.channels.Channels.flushBlocking(Channels.java:63) [xnio-api-3.2.2.Final.jar:3.2.2.Final]
at io.undertow.servlet.spec.ServletOutputStreamImpl.close(ServletOutputStreamImpl.java:625)
at io.undertow.servlet.spec.HttpServletResponseImpl.closeStreamAndWriter(HttpServletResponseImpl.java:451)
at io.undertow.servlet.spec.HttpServletResponseImpl.responseDone(HttpServletResponseImpl.java:525)
... 9 more

The requested pages appear to load without a problem, so other than the exceptions in the log, I haven't noticed any breaks. Any ideas?

Answer

Manu picture Manu · Jan 22, 2015

I've face a similar problem and thanks to the idea of this response, I advanced a little it. I'm going to expose my case.

I was creating a REST API using Java (Java 7) (javax.ws.rs) and deploying it on a JBoss server (8.x).

My Api responds to these paths:

  • /myapi/a
  • /myapi/a?filer=myfilter

So I code it this way:

private static final String FILTER = "filter";

@GET
@Path("/a")
@Produces(MediaType.APPLICATION_JSON)
public Object
foo(@Context UriInfo requestInfo) {
    LOG.info("Http request: GET /myapi/a");
    if (requestParameters.getQueryParameters().containsKey(FILTER)) {
            return foo(requestInfo.getQueryParameters().get(FILTER));
    } 
    // no params
    return ...
}


public Object foo(List<String> filter) {
    LOG.info(" > Requested filter"); 
    return ...;
}

But I was getting sometimes this exception from the server (not my code) UT005023: Exception handling request to ... sessionState: org.jboss.resteasy.spi.UnhandledException: Response is committed, can't handle exception caused by java.io.IOException: Broken pipe

Investigating it I come across something really interesting: it was only able to reproduce it from Safari browser, not Chrome. So what? The point is that Safari has a functionality Chrome doesn't: When Safari auto-completes the request, it sends the request. Chrome doesn't send the request until the enter button is pressed. And this is important because the bug appears only if:

  1. request with Safari's autocomplete to /a?filter=f
  2. request (hitting enter) to /a

At this point, I don't know the reason (it's something related to the http header) => as stephen-c, the problem is that you are trying to do stuff that would require a change to the HTTP response headers ... after the headers have been sent

[EDITED]

I'm almost sure (99%) that we could not handled that exception. basically it's saying that you have lose one request and, as a warning, the server is telling you that you're not going to handle it.

There is another way to recreate the exception: try to put your finger at F5 or CMD-R. Your are going to create hundred of requests... but you'll lose some of them (related to pool thread, workers, etc) and you'll see the exception for those lose requests.

I've decided not to worry about this anymore.