Skip to content

Error metadata is sent as trailers instead of headers in unary RPCs #850

Description

@frozenbonito

Describe the bug

When setting metadata on an error, the metadata is sent as a trailer even for Unary RPCs.

According to the documentation for Error.Meta, I expected the metadata to be sent as headers:

Metadata attached to errors returned by unary handlers is always sent as HTTP headers, regardless of the protocol.

To Reproduce

A reproduction repository is available here:
https://github.com/frozenbonito/connect-error-metadata

The main.go file starts a Connect server that returns an error with attached metadata, then uses a grpc-go client to call it and inspect the headers and trailers.
For comparison, it also includes a similar grpc-go server and performs the same inspection.

$ git clone https://github.com/frozenbonito/connect-error-metadata
$ cd connect-error-metadata/
$ go run main.go
Connect
rpc error: code = Unimplemented desc = unimplemented
header: map[content-type:[application/grpc] date:[Thu, 05 Jun 2025 01:19:53 GMT] grpc-accept-encoding:[gzip]]
trailer: map[custom-key:[value]]
-----------------
gRPC
rpc error: code = Unimplemented desc = unimplemented
header: map[content-type:[application/grpc] custom-key:[value]]
trailer: map[]

custom-key is the metadata added by the handler.

Environment (please complete the following information):

  • connect-go version or commit: v1.18.1
  • go version: go version go1.24.3 linux/amd64
  • your complete go.mod:
module github.com/frozenbonito/connect-error-metadata

go 1.24.3

require (
	connectrpc.com/connect v1.18.1
	golang.org/x/net v0.35.0
	google.golang.org/grpc v1.72.2
	google.golang.org/protobuf v1.36.6
)

require (
	golang.org/x/sys v0.30.0 // indirect
	golang.org/x/text v0.22.0 // indirect
	google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
)

Additional context
As demonstrated in the reproduction code, grpc-go sends metadata as headers even for error responses.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions