When updating Spring Boot to version 2.2.0 I get an error when trying to upload a file.
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: Stream closed
Error code
@RestController
public class FileController {
@PostMapping("/api/file")
public ResponseEntity<String> upload(@RequestParam("file") MultipartFile multipartFile) {
//...
}
}
This code worked for me on versions less than 2.2.0
Comment From: wilkinsona
Thanks for the report. I would guess from the exception that something is closing the network connection before the upload has completed. That could, perhaps, be due to a timeout or a problem with the client. If you would like us to spend some time investigating, can you please take the time to provide a complete and minimal example that reproduces the problem in the form of a zipped project attached to this issue.
Comment From: isimonov
The problem did not reproduce on the new empty project. Perhaps in the new version of the framework the mechanism for working with request inputStream has changed in the case of multipart/form-data content ... and this is not fixed in the project where a MultipartException occurs. I propose to close this issue.
Comment From: wilkinsona
Ok, thanks for letting us know. If you encounter the problem again in a reproducible manner, please comment here with a sample and we'll gladly take another look.
Comment From: grimsa
I ran into the same issue.
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: Stream closed
Worked fine on Spring Boot 2.1.12, failed after upgrade to 2.2.4 (both versions run the same embedded Tomcat 9.0.30).
The root cause was that we were using logback-access filter that logs requests and responses.
The filter wrapped HttpServletRequest with a caching wrapper and closed the input stream before passing the request along the filter chain.
This caused an issue when javax.servlet.http.HttpServletRequest#getParts was called, as that call is delegated to the original Tomcat's request (with a now-closed input stream), which then results in the "stream closed" exception.
The Spring change that triggered this issue is hiddenHttpMethodFilter no longer being present in the filter chain.
Previously this filter would be one of the first filters to be called, and it would call HttpServletRequest#getParameter, which in turn would make Tomcat's request implementation parse multipart content and store the parts in the object (so that later calls to #getParts would use that and not try to parse them again).
I reported this to Logback: https://jira.qos.ch/browse/LOGBACK-1503
Workaround - call HttpServletRequest#getParameter before passing the request to logback's filter (see LOGBACK-1503 for code), to force Tomcat to parse and store request parts while input stream is still open.
Comment From: knight0707
I encounter the same error with SpringBoot 2.2+. When I change SpringBoot version to 2.1.13.RELEASE , everything works well .
Comment From: snicoll
@knight0707 if you share a small sample (a zip or a link to a github repo) that shows it work with 2.1x and fail with 2.2x (by just changing the version) we can reopen this issue.
Comment From: xiaolong7yang
I also encountered this problem in the 2.2.6 version. I built a repeatable request.getInputStream(). It is convenient for me to verify the security problem, but after upgrading to it, it will stream closed. Do you have any solutions?
Comment From: grimsa
@snicoll @wilkinsona Here's a sample that works on 2.1.x but fails on 2.2.x: https://github.com/grimsa/spring-boot-18644-sample
Comment From: xiaolong7yang
spring:
mvc:
hiddenmethod:
filter:
enabled: true
Open this filter and the problem will be solved
Comment From: ethan-jo
yaml spring: mvc: hiddenmethod: filter: enabled: trueOpen this filter and the problem will be solved
Works for me.
Comment From: umanking
@snicoll @wilkinsona Here's a sample that works on 2.1.x but fails on 2.2.x: https://github.com/grimsa/spring-boot-18644-sample
how about spring boot 2.3.x ? is it okay?
Comment From: philwebb
@umanking 2.3 is likely to have the same issue but I don't think there's anything that we can do about this in Spring Boot. Someone needs to probably get involved with a fix for LOGBACK-1503.
Comment From: Caratacus
mark
Comment From: San500
Working with spring boot version: 2.3.0.RELEASE groupId: org.springframework.boot artifactId: spring-boot-starter-parent version: 2.3.0.RELEASE
when i try to upload 1 GB file then i am facing an error:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.impl.IOFileUploadException: Processing of multipart/form-data request failed. java.io.EOFException: Unexpected EOF read on the socket] with root cause
java.io.EOFException: Unexpected EOF read on the socket
ERROR CODE:
@RestController
public class FileController {
@PostMapping("/api/file")
public ResponseEntity<String> upload(@RequestParam("file") MultipartFile multipartFile) {
//...
}
}
Comment From: wilkinsona
@San500 Without knowing more about your problem (which web container you are using, if the problem only occurs with large (1GB files) or also with smaller files, whether you're using Logback's TeeFilter, etc), it's difficult to help you. If you'd like some help please come and chat on Gitter or ask a question on Stack Overflow.
Comment From: ghost
Change request method from PUT to post, the problem will be solved.
Comment From: haardiksikka
yaml spring: mvc: hiddenmethod: filter: enabled: trueOpen this filter and the problem will be solved
After placing this in yml file, working fine for Post requests but causing same problem for put request.
Comment From: drgnchan
i found that the request succeed when spring.mvc.hiddenMethod.filter.enabled is true and the request method is POST because HiddenHttpMethodFilter will invoke request.getParameter() in mehtod doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain).And the invocation of request.getParameter() is invoked before the TeeFilter which will close the stream.
is there any possibility to place the invocation of Request.parseParameters() at very early stage?
Comment From: SwapnilThange
i am also getting same error but in my case its EOFexception
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.impl.IOFileUploadException: Processing of multipart/form-data request failed. java.io.EOFException
Comment From: SwapnilThange
Unexpected EOF read on the socket
Working with spring boot version: 2.3.0.RELEASE groupId: org.springframework.boot artifactId: spring-boot-starter-parent version: 2.3.0.RELEASE
when i try to upload 1 GB file then i am facing an error:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.impl.IOFileUploadException: Processing of multipart/form-data request failed. java.io.EOFException: Unexpected EOF read on the socket] with root cause
java.io.EOFException: Unexpected EOF read on the socket
ERROR CODE:
java @RestController public class FileController { @PostMapping("/api/file") public ResponseEntity<String> upload(@RequestParam("file") MultipartFile multipartFile) { //... } }
it is solved for you?, if yes I am interested to know how. In my case, I get this error for the file of size < 300MB. It occurs randomly
Comment From: Gavinollap-nd
is this problem solved?
Comment From: riankrishandi
I'm facing similar issue with Spring Boot version 3.3.0 with Apache Tomcat 10.1.24. From my debug, I got the exception was thrown when HttpServletRequestWrapper.getParts().
Following the Spring doc, I have set my Spring config as below but error still occurred.
spring:
servlet:
multipart:
enabled: true
max-file-size: 10MB
max-request-size: 10MB
file-size-threshold: 10MB
For temp quick solution, I did as @xiaolong7yang suggested.