Skip to content

Duplicate response headers with ResponseEntity<Mono<T>> (or Kotlin suspend function) controller method #36357

@deftfitf

Description

@deftfitf

Duplicate response headers with Kotlin suspend function returning ResponseEntity after header adapter optimization

Affects: Spring Framework 7.0.5 (Spring Boot 4.0.3)

Maybe introduced in: 7ea11baff9 (Pass-through handling of Servlet headers, gh-36334)

Description

After the Servlet header adapter optimization introduced in gh-36334, response headers are duplicated when a Kotlin suspend fun controller method returns ResponseEntity<T> in Spring WebMVC.

The root cause is in ResponseBodyEmitterReturnValueHandler.handleReturnValue(). In the non-streaming path (single-value reactive type adapted to DeferredResult), headers that are already present in the HttpServletResponse are read back through the adapter and re-added via addHeader(), resulting in every header appearing twice.

First, the header is copied here.

The http header is also duplicated in the outputMessage.

response.addHeader causes a duplicate header in the original response.

Steps to Reproduce

  1. Configure a CorsFilter or @CrossOrigin annotation
  2. Define a Kotlin suspend controller that returns ResponseEntity<T>:
@RestController
class MyController {

    @GetMapping("/example")
    suspend fun example(): ResponseEntity<String> {
        return ResponseEntity.ok()
            .header("X-Custom", "value")
            .body("hello")
    }
}
  1. Send a cross-origin request to /example
  2. Observe the response headers

Expected Behavior

Each header appears once in the response

Actual Behavior

Headers are duplicated

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: regressionA bug that is also a regression

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions