Skip to content

Jetty 12.0.8 seems to leak connection when it encounters earlyEOF #11679

@LarsKrogJensen

Description

@LarsKrogJensen

Jetty version(s)
12.0.8

Jetty Environment
ee10

Java version/vendor (use: java -version)
java 21.0.2 2024-01-16 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 21.0.2+13.1 (build 21.0.2+13-LTS-jvmci-23.1-b30)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 21.0.2+13.1 (build 21.0.2+13-LTS-jvmci-23.1-b30, mixed mode, sharing)

OS type/version
Ubuntu 22.04

Description
We have seen a clear increase of requests from mobile clients where jetty fails to handle/parse the request body and causes HttpConnection$RequestHandler.earlyEOF to trigger.
That in itself is perhaps not alarming, but it seems that this causes Jetty to leak requests and connection, we can see a steady increase in our metrics of QoSHandler's active requests. Eventually QoS hits the max active requests and starts rejecting requests.

We have a very strong correlation between these errors and leaking connections/requests.

Other sites where we do not see these errors we do not see any leakage.

How to reproduce?
I am afraid I have not been able to reproduce to make jetty trigger HttpParser.earlyEOF, not sure how to simulate a bad client :(

Stacktrace
message: "Error while closing the output stream in order to commit response"
stacktrace:

org.glassfish.jersey.server.ServerRuntime$Responder: org.eclipse.jetty.http.BadMessageException: 400: Early EOF
	at o.e.j.s.internal.HttpConnection$RequestHandler.earlyEOF(HttpConnection.java:1051)
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1729)
	at org.eclipse.jetty.server.internal.HttpConnection.parseRequestBuffer(HttpConnection.java:568)
	at org.eclipse.jetty.server.internal.HttpConnection.parseAndFillForContent(HttpConnection.java:493)
	at o.e.j.s.i.HttpConnection$HttpStreamOverHTTP1.read(HttpConnection.java:1346)
	at org.eclipse.jetty.server.HttpStream$Wrapper.read(HttpStream.java:161)
	at o.e.j.s.internal.HttpChannelState$ChannelRequest.read(HttpChannelState.java:888)
	at org.eclipse.jetty.server.Request$Wrapper.read(Request.java:791)
	at o.e.j.server.handler.EventsHandler$EventsRequest.read(EventsHandler.java:376)
	at org.eclipse.jetty.server.Request$Wrapper.read(Request.java:791)
	at o.eclipse.jetty.ee10.servlet.AsyncContentProducer.readChunk(AsyncContentProducer.java:319)
	at o.eclipse.jetty.ee10.servlet.AsyncContentProducer.produceChunk(AsyncContentProducer.java:305)
	at o.eclipse.jetty.ee10.servlet.AsyncContentProducer.isReady(AsyncContentProducer.java:243)
	at o.e.jetty.ee10.servlet.BlockingContentProducer.nextChunk(BlockingContentProducer.java:108)
	at org.eclipse.jetty.ee10.servlet.HttpInput.read(HttpInput.java:244)
	at org.eclipse.jetty.ee10.servlet.HttpInput.read(HttpInput.java:225)
	at o.g.jersey.message.internal.EntityInputStream.read(EntityInputStream.java:79)
	at o.g.j.m.i.ReaderInterceptorExecutor$UnCloseableInputStream.read(ReaderInterceptorExecutor.java:276)
	at c.f.jackson.core.json.ByteSourceJsonBootstrapper.ensureLoaded(ByteSourceJsonBootstrapper.java:547)
	at c.f.jackson.core.json.ByteSourceJsonBootstrapper.detectEncoding(ByteSourceJsonBootstrapper.java:137)
	at c.f.jackson.core.json.ByteSourceJsonBootstrapper.constructParser(ByteSourceJsonBootstrapper.java:266)
	at com.fasterxml.jackson.core.JsonFactory._createParser(JsonFactory.java:1863)
	at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:1262)
	at o.g.j.j.internal.jackson.jaxrs.base.ProviderBase._createParser(ProviderBase.java:843)
	at o.g.j.j.internal.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:787)
	at o.g.j.m.i.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:235)
	at o.g.j.m.i.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:214)
	at o.g.j.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
	at o.g.j.s.i.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:49)
	at o.g.j.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
	at o.g.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1072)
	at o.g.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:657)
	at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:290)
	at o.g.j.s.i.i.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:73)
	at o.g.j.s.i.i.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:56)
	at o.g.j.s.spi.internal.ParamValueFactoryWithSource.apply(ParamValueFactoryWithSource.java:50)
	at o.g.j.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:68)
	at o.g.j.s.m.i.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:109)
	at o.g.j.s.m.i.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:159)
	at o.g.j.s.m.i.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:93)
	at o.g.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478)
	at o.g.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400)
	at o.g.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
	at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:263)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
	at o.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:266)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:242)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:697)
	at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:312)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
	at org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:736)
	at o.e.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1614)
	at c.k.p.f.rest.filter.RequestContextBindingFilter.doFilter(RequestContextBindingFilter.java:63)
	at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)
	at o.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1586)
	at o.e.j.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1547)
	at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:819)
	at org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:431)
	at org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:464)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
	at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:851)
	at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
	at org.eclipse.jetty.server.handler.ResourceHandler.handle(ResourceHandler.java:164)
	at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
	at o.eclipse.jetty.server.handler.CrossOriginHandler.handle(CrossOriginHandler.java:375)
	at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
	at o.eclipse.jetty.server.handler.ConditionalHandler.nextHandler(ConditionalHandler.java:421)
	at org.eclipse.jetty.server.handler.QoSHandler.handleWithPermit(QoSHandler.java:266)
	at org.eclipse.jetty.server.handler.QoSHandler.onConditionsMet(QoSHandler.java:191)
	at o.eclipse.jetty.server.handler.ConditionalHandler.handle(ConditionalHandler.java:378)
	at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
	at c.k.p.frontend.ratelimiter.PunterThrottlingHandler.handle(PunterThrottlingHandler.java:36)
	at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
	at c.k.k.jetty.KelogsTracingHandler.handle(KelogsTracingHandler.java:53)
	at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
	at org.eclipse.jetty.server.handler.EventsHandler.handle(EventsHandler.java:81)
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:597)
	at org.eclipse.jetty.server.Server.handle(Server.java:179)
	at o.e.j.s.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:619)
	at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:411)
	at o.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:99)
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
	at j.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
	at java.lang.VirtualThread.run(VirtualThread.java:309)

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugFor general bugs on Jetty side

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions