0

I am building a simple API using SpringBoot. Receives input through RequestBody and prints it out..

However, as the size of the RequestBody increases, the following error occurs. It doesn't happen unconditionally, it sometimes succeeds...

2021-02-15 03:52:50.028  WARN 5115 --- [nio-8443-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is org.apache.catalina.connector.ClientAbortException: java.io.EOFException]
2021-02-15 03:52:50.037 ERROR 5115 --- [nio-8443-exec-3] o.a.c.c.C.[Tomcat].[localhost]           : Exception Processing ErrorPage[errorCode=0, location=/error]

org.apache.catalina.connector.ClientAbortException: org.apache.coyote.CloseNowException: Connection [{0}], Stream [{1}], This stream is not writable
        at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:309) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:272) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:118) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at java.base/java.io.FilterOutputStream.flush(FilterOutputStream.java:153) ~[na:na]
        at com.fasterxml.jackson.core.json.UTF8JsonGenerator.flush(UTF8JsonGenerator.java:1178) ~[jackson-core-2.11.4.jar!/:2.11.4]
        at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1008) ~[jackson-databind-2.11.4.jar!/:2.11.4]
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:345) ~[spring-web-5.3.3.jar!/:5.3.3]
        at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104) ~[spring-web-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:277) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:219) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) ~[spring-web-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.41.jar!/:4.0.FR]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.3.jar!/:5.3.3]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.41.jar!/:4.0.FR]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.3.jar!/:5.3.3]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar!/:5.3.3]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103) ~[spring-web-5.3.3.jar!/:5.3.3]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103) ~[spring-web-5.3.3.jar!/:5.3.3]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:461) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:398) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:257) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:179) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.StreamProcessor.service(StreamProcessor.java:405) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.StreamProcessor.process(StreamProcessor.java:74) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.StreamRunnable.run(StreamRunnable.java:35) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
Caused by: org.apache.coyote.CloseNowException: Connection [{0}], Stream [{1}], This stream is not writable
        at org.apache.coyote.http2.Stream.doStreamCancel(Stream.java:255) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.Http2UpgradeHandler.reserveWindowSize(Http2UpgradeHandler.java:856) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.Stream$StreamOutputBuffer.flush(Stream.java:901) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.Stream$StreamOutputBuffer.flush(Stream.java:847) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.Stream$StreamOutputBuffer.flush(Stream.java:970) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.Http2OutputBuffer.flush(Http2OutputBuffer.java:77) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.http2.StreamProcessor.flush(StreamProcessor.java:234) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:402) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.coyote.Response.action(Response.java:209) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:305) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        ... 51 common frames omitted
Caused by: org.apache.coyote.http2.StreamException: Connection [{0}], Stream [{1}], This stream is not writable
        at org.apache.coyote.http2.Stream.doStreamCancel(Stream.java:247) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
        ... 60 common frames omitted

https://pastebin.com/PRHwJ8XM

Spring Boot configuration including

  1. spring.servlet.multipart.max-file-size
  2. spring.servlet.multipart.max-request-size
  3. server.max-http-form-post-size
  4. server.max-swallow-size
  5. server.tomcat.connection-timeout

and nginx I have modified all the settings.

It didn't happen over time that the error occurred, but the error occurred as soon as I sent the POST request. The small body still works well...

The client encodes the image file as Base64 and passes the encoding result as JSON. If the length of Base64 is short, it will be processed without any problems, but if the length is longer, a corresponding error occurs.

If you have any relevant experience, I ask for advice on how to fix it.

Keriel
  • 3
  • 3

3 Answers3

1

Find the server.xml of tomcat and modify the value:

<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" overheadDataThreshold=0 />

Set overheadDataThreshold to 0

peter
  • 81
  • 2
  • Remember to restart your server after modification – peter Feb 15 '21 at 07:39
  • I am using spring boot's built-in tomcat. Can I modify server.xml here? With regard to http2, I did have server.http2.enabled = true in application.yml – Keriel Feb 15 '21 at 08:20
  • Setting server.http2.enabled to false works fine. Any idea why this is happening with the http2 protocol? Or do you have documentation? Thanks. – Keriel Feb 15 '21 at 08:26
  • enabled = false; does work normally, I am not very clear about the specific reasons, but I guess it may be due to the difference in data transmission between HTTP1.1 and HTTP2. HTTP2 uses a new method called data fragment transmission. If the data is too large, this seems to cause some problems. For specific reasons, I suggest you consult the related documents of HTTP2. – peter Feb 16 '21 at 08:42
0

Check out Tomcat Bug maybe this is your case.

space
  • 29
  • 3
0

Add in application.properties

server.http2.enabled=true

Adir Dayan
  • 1,308
  • 13
  • 21