ResponseWriter treats informational HTTP responses as final responses
In what area(s)?
/area runtime
HTTP response middleware (pkg/responsewriter).
What version of Dapr?
Reproduced on master at 378f9fc9baa7fc45ff9a7d10d23750f0f2677081, using Go 1.26.8 on macOS arm64. This reproduction uses a local Go HTTP server, without Kubernetes or external services.
Expected behavior
Writing two 103 Early Hints responses followed by 201 Created should send both informational responses and the final 201 response. The wrapper should record the final status. 101 Switching Protocols should retain its terminal behavior, matching Go's HTTP server.
Actual behavior
The wrapper marks the first 103 as written. The second 103 and final 201 are ignored. When the handler writes a body, the underlying HTTP server emits an implicit 200, while the wrapper still records 103.
Steps to Reproduce the Problem
Wrap the writer in an httptest.NewServer handler:
rw := responsewriter.NewResponseWriter(w)
rw.WriteHeader(http.StatusEarlyHints)
rw.WriteHeader(http.StatusEarlyHints)
rw.WriteHeader(http.StatusCreated)
_, _ = rw.Write([]byte("created"))The client receives 200 rather than 201, and httptrace.ClientTrace.Got1xxResponse observes only one 103. The same sequence on the unwrapped standard writer supports informational responses followed by the final response.
Proposed fix and validation
Forward 100–199 responses other than 101 without committing the wrapper's final status, then use the existing path for the final response. Keep final-response Before callbacks and protocol-switch behavior covered by regression tests.
A local patch and three tests are ready. On the original source, two tests fail; with the fix, all 15 package tests pass with the race detector, and golangci-lint 2.10.1 reports no issues for the package with the repository's configuration/build tags. Full Dapr end-to-end tests were not run.
This is distinct from #9955, which addresses Flush() status tracking. No changes to Flush are included.
AI disclosure: Codex assisted with investigation, the local patch, tests, and this report.
Release Note
RELEASE NOTE: FIX Preserve the final HTTP response status after informational responses in the response writer wrapper.
Source: dapr/dapr