Describe the bug I have simple SpringMVC Controller returning StreamingResponseBody

@RestController
class SampleController {
    @RequestMapping("/streaming" ,method = [GET])
    fun data(): ResponseEntity<StreamingResponseBody> {
        return ResponseEntity(
            StreamingResponseBody { out ->
                out.write("some data".toByteArray())
            }, HttpStatus.OK)
    }
}

and there is simple test for this controller

@WebMvcTest(SampleController::class)
@ContextConfiguration(classes = [SampleController::class])

internal class SampleControllerTest {
    @Autowired
    lateinit var mockMvc: MockMvc
    @Autowired
    lateinit var controller: SampleController

    @WithMockUser("my-user")
    @Test
    @RepeatedTest(100)
    fun `StreamingResponseBody response in combination with spring security sometimes fail`() {
        // when
        val response = mockMvc.perform(MockMvcRequestBuilders.get("/streaming")).andReturn().response
        // then
        assertThat(response.status).isEqualTo(HttpStatus.OK.value())
    }
}

most of the time, the test is OK, but in some cases there is NPE:

java.lang.NullPointerException
    at org.springframework.mock.web.MockHttpServletResponse.doAddHeaderValue(MockHttpServletResponse.java:676)
    at org.springframework.mock.web.MockHttpServletResponse.addHeaderValue(MockHttpServletResponse.java:629)
    at org.springframework.mock.web.MockHttpServletResponse.addHeader(MockHttpServletResponse.java:603)
    at javax.servlet.http.HttpServletResponseWrapper.addHeader(HttpServletResponseWrapper.java:174)
    at org.springframework.security.web.firewall.FirewalledResponse.addHeader(FirewalledResponse.java:60)
    at javax.servlet.http.HttpServletResponseWrapper.addHeader(HttpServletResponseWrapper.java:174)
    at org.springframework.security.web.util.OnCommittedResponseWrapper.addHeader(OnCommittedResponseWrapper.java:64)
    at org.springframework.security.web.header.writers.StaticHeadersWriter.writeHeaders(StaticHeadersWriter.java:64)
    at org.springframework.security.web.header.HeaderWriterFilter.writeHeaders(HeaderWriterFilter.java:99)
    at org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterResponse.writeHeaders(HeaderWriterFilter.java:133)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:93)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183)
    at SampleControllerTest.StreamingResponseBody response in combination with spring security sometimes fail(SampleControllerTest.kt:30)
    at jdk.internal.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
 .... omitted ...

To Reproduce run tests

Expected behavior all tests should pass

Sample there is link to sample project with tests https://github.com/vloo/streaming-response-body-sample

Comment From: eleftherias

Thank you for the sample. It looks like this is a duplicate of gh-9175 (see gh-9176 for the reasoning).

I used the workaround of setting HeaderWriterFilter.shouldWriteHeadersEagerly = true on the sample you provided and the tests passed ever time. Can you confirm whether that works for you?

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.