Skip to content

Response headers set in handler are lost when handler returns an error #885

@whisper0077

Description

@whisper0077

I'm very pleased with the simple flag feature! I tried it right away and found a bug.

Describe the bug

When an error occurs, values set in CallInfo.ResponseHeader() are not reflected in the response.

To Reproduce

The reproduction code is as follows.
https://github.com/whisper0077/connect-go/blob/main/example/main.go

  1. Server Ping handler sets response header "x-custom-key: value" and returns an error if request.Number < 0
  2. Client calls Ping with Number = 1 (success) and Number = -1 (error), then inspects callInfo.ResponseHeader()
  • Observed behavior
    For the successful call, the response header is present.
    For the error call, the response header is absent.

  • Expected behavior
    Headers set by the handler should be sent to the client even when the handler returns an error.

$ git clone https://github.com/whisper0077/connect-go
$ cd example
$ go run main.go
2025/09/26 19:22:31 response header  ok: value
2025/09/26 19:22:31 response header err: 

Environment (please complete the following information):

  • connect-go version or commit: v1.19.0
  • go version: go1.25.1 linux/amd64
  • your complete go.mod:
module connectrpc.com/connect

go 1.24.0

retract (
	v1.10.0 // module cache poisoned, use v1.10.1
	v1.9.0 // module cache poisoned, use v1.9.1
)

require (
	github.com/google/go-cmp v0.5.9
	google.golang.org/protobuf v1.36.9
)

Additional context
Related issue: #850

In the code below, performing the merge of the response headers before returning the error appears to resolve the issue. Potential impacts on other components have not been examined.
https://github.com/connectrpc/connect-go/blob/v1.19.0/handler.go#L78-L90

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions