-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
2.2.25.Final, 2.3.7.Final
-
None
An incomplete response can still be seen with TLSv1.3 and NewSessionTickets after UNDERTOW-2413.
Undertow TRACE shows the connection close from some exception in io.undertow.server.protocol.http.HttpResponseConduit.write:
2025-06-17 14:46:52,099 TRACE [io.undertow.request.io] (default task-3) Exception closing read side of SSL channel: javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify at java.base/sun.security.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:794) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.protocols.ssl.SslConduit.notifyReadClosed(SslConduit.java:638) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.protocols.ssl.SslConduit.closed(SslConduit.java:1096) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.protocols.ssl.SslConduit.close(SslConduit.java:1237) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.protocols.ssl.UndertowSslConnection.closeAction(UndertowSslConnection.java:163) at org.jboss.xnio@3.8.16.Final-redhat-00001//org.xnio.Connection.close(Connection.java:132) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.server.AbstractServerConnection.close(AbstractServerConnection.java:159) at org.jboss.xnio@3.8.16.Final-redhat-00001//org.xnio.IoUtils.safeClose(IoUtils.java:152) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.server.protocol.http.HttpResponseConduit.write(HttpResponseConduit.java:681) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.conduits.ChunkedStreamSinkConduit.doWrite(ChunkedStreamSinkConduit.java:166) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.conduits.ChunkedStreamSinkConduit.write(ChunkedStreamSinkConduit.java:128) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.conduits.ChunkedStreamSinkConduit.write(ChunkedStreamSinkConduit.java:223) at org.jboss.xnio@3.8.16.Final-redhat-00001//org.xnio.conduits.ConduitStreamSinkChannel.write(ConduitStreamSinkChannel.java:158) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.channels.DetachableStreamSinkChannel.write(DetachableStreamSinkChannel.java:179) at io.undertow.core@2.3.18.SP1-redhat-00001//io.undertow.server.HttpServerExchange$WriteDispatchChannel.write(HttpServerExchange.java:2206) at org.jboss.xnio@3.8.16.Final-redhat-00001//org.xnio.channels.Channels.writeBlocking(Channels.java:202) at io.undertow.servlet@2.3.18.SP1-redhat-00001//io.undertow.servlet.spec.ServletOutputStreamImpl.writeBlocking(ServletOutputStreamImpl.java:1002) at io.undertow.servlet@2.3.18.SP1-redhat-00001//io.undertow.servlet.spec.ServletOutputStreamImpl.writeTooLargeForBuffer(ServletOutputStreamImpl.java:202) at io.undertow.servlet@2.3.18.SP1-redhat-00001//io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:149) at deployment.AdapterServices.war//org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:51)
Additional byteman tracing clarified that the original exception is also thrown by io.undertow.server.protocol.http.HttpResponseConduit.processWrite as the buffer reference was seen as null:
>Wed Jun 25 14:01:11 GMT 2025 default task-5 exception caught: null java.nio.channels.ClosedChannelException.<init>(ClosedChannelException.java:53) io.undertow.server.protocol.http.HttpResponseConduit.processWrite(HttpResponseConduit.java:130) io.undertow.server.protocol.http.HttpResponseConduit.write(HttpResponseConduit.java:666) io.undertow.conduits.ChunkedStreamSinkConduit.doWrite(ChunkedStreamSinkConduit.java:166) io.undertow.conduits.ChunkedStreamSinkConduit.write(ChunkedStreamSinkConduit.java:128) io.undertow.conduits.ChunkedStreamSinkConduit.write(ChunkedStreamSinkConduit.java:223) org.xnio.conduits.ConduitStreamSinkChannel.write(ConduitStreamSinkChannel.java:158) io.undertow.channels.DetachableStreamSinkChannel.write(DetachableStreamSinkChannel.java:179) io.undertow.server.HttpServerExchange$WriteDispatchChannel.write(HttpServerExchange.java:2206) org.xnio.channels.Channels.writeBlocking(Channels.java:202) io.undertow.servlet.spec.ServletOutputStreamImpl.writeBlocking(ServletOutputStreamImpl.java:1002) io.undertow.servlet.spec.ServletOutputStreamImpl.writeTooLargeForBuffer(ServletOutputStreamImpl.java:202) io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:149) org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:51) com.ctc.wstx.sw.EncodingXmlWriter.flushBuffer(EncodingXmlWriter.java:742) com.ctc.wstx.sw.ISOLatin1XmlWriter.writeRaw(ISOLatin1XmlWriter.java:110) com.ctc.wstx.sw.EncodingXmlWriter.writeNameUnchecked(EncodingXmlWriter.java:911) com.ctc.wstx.sw.EncodingXmlWriter.writeEndTag(EncodingXmlWriter.java:481) com.ctc.wstx.sw.BaseNsStreamWriter.doWriteEndTag(BaseNsStreamWriter.java:725) com.ctc.wstx.sw.BaseNsStreamWriter.writeEndElement(BaseNsStreamWriter.java:285)
Debugging further and comparing EAP 7.4.11's working response, I see the HttpResponseConduit.processWrite for the NST write attempt returns here] without a bufferDone call occurring. So the failure seems introduced in EAP 7.4.12+ from UNDERTOW-2247 since bufferDone is now always called in the HttpResponseConduit.processWrite finally. The bufferDone from UNDERTOW-2247 now clears the buffer reference so the next HttpResponseConduit.processWrite for the large request throws an exception and terminates prematurely.
So it seems we should call bufferDone only under more select circumstances.
- is caused by
-
UNDERTOW-2413 CVE-2024-5971 undertow: response write hangs in case of Java 17 TLSv1.3 NewSessionTicket
-
- Closed
-
- is cloned by
-
JBEAP-30615 [GSS](8.0.z) UNDERTOW-2588 - Undertow response can still break in case of Java 17 TLSv1.3 NewSessionTicket
-
- Pull Request Sent
-