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: true

Open 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: true

Open 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.