-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Jetty version(s)
12.0.33
Jetty Environment
core
HTTP version
HTTP 1.1
Java version/vendor
OpenJDK 17
OS type/version
AlmaLinux 8
Description
HttpChannelState.completeStream() throws a NullPointerException when cleaning up multipart form data if _request has already been nulled by recycle().
The crash occurs at HttpChannelState.java:642:
MultiPartFormData.Parts parts = MultiPartFormData.getParts(_request);MultiPartFormData.getParts(Attributes) does not guard against a null argument, and _request can be null if recycle() has already run.
Stack trace:
java.lang.NullPointerException: Cannot invoke "org.eclipse.jetty.util.Attributes.getAttribute(String)" because "attributes" is null
at org.eclipse.jetty.http.MultiPartFormData.getParts(MultiPartFormData.java:129)
at org.eclipse.jetty.server.internal.HttpChannelState.completeStream(HttpChannelState.java:642)
at org.eclipse.jetty.server.internal.HttpChannelState$LastWriteCallback.completeLastWrite(HttpChannelState.java:800)
at org.eclipse.jetty.server.internal.HttpChannelState$LastWriteCallback.succeeded(HttpChannelState.java:775)
at org.eclipse.jetty.util.thread.Invocable$ReadyTask.run(Invocable.java:177)
at org.eclipse.jetty.util.thread.SerializedInvoker$Link.run(SerializedInvoker.java:268)
at org.eclipse.jetty.util.thread.SerializedInvoker.run(SerializedInvoker.java:168)
at org.eclipse.jetty.server.internal.HttpChannelState$ChannelResponse.failed(HttpChannelState.java:1396)
at org.eclipse.jetty.io.AbstractConnection.lambda$failedCallback$0(AbstractConnection.java:99)
The call path suggests a connection failure (client disconnect) during response writing, where the failure handling races with channel recycling. The AbstractConnection.failedCallback origin indicates the underlying connection failed while the response write was still in progress.
How to reproduce?
We observe this sporadically in production when handling multipart/form-data requests (file uploads) under load with keep-alive connections. We believe it occurs when the client disconnects before the server finishes writing the response.