gRPC server instrumentations (grpc-1.5, armeria-grpc) don't make extracted W3C baggage current in the handler
Mantenedores costumam responder em até 2 dias
@mcculls já está trabalhando nisso.
Desde 28/9/2026.
Avaliação
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Facilidade para iniciantes
- 78/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- grpc, java
- Domínio
- observability
Direção de pesquisa
Start with the extraction and activation paths in dd-java-agent/instrumentation/grpc-1.5/.../TracingServerInterceptor.java and the corresponding armeria-grpc-0.84 file, then run the GrpcServerBaggageTest reproduction. Compare them with HttpServerDecorator and JettyServerAdvice; done means inbound baggage is current in the unary handler and is reinjected on outbound calls while trace propagation still works.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Tracer Version(s)
1.56.0, 1.66.0 (observed); master at 02d50d2 (code reading)
Java Version(s)
17.0.13
JVM Vendor
Eclipse Adoptium / Temurin
Bug Report
gRPC server instrumentations (grpc-1.5 and armeria-grpc-0.84) extract inbound W3C baggage but don't make it current while the service runs. As a result:
Baggage.current()(OTel API,DD_TRACE_OTEL_ENABLED=true) is empty inside the handler.- Downstream calls from the handler carry no
baggageheader, even though the trace context (x-datadog-*,traceparent) propagates fine.
The baggage.* span tags still show up on the grpc.server span, which makes the loss easy to miss.
Root cause. Both TracingServerInterceptors call the deprecated AgentPropagation.extractContextAndGetSpanContext (internal-api, v1.66.0 L33-L38).
- That helper extracts the full
Contextand then returns only the span context, so the extractedBaggageelement is discarded. - The interceptor then runs
next.startCall(...)and every listener callback underactivateSpan(span), which is a span-only context. - The tags appear anyway because
BaggagePropagator.extractalso copies the baggage onto the extractedTagContext(v1.66.0 L130-L138).
Call sites:
armeria-grpc-0.84: extract L71, activate L94grpc-1.5: extract L72, activate L95
HTTP servers don't have this problem. They were moved to full-context extraction in #8820: HttpServerDecorator.extract returns the whole Context, and e.g. JettyServerAdvice attaches parentContext.with(span) (v1.66.0 L32-L61).
Observed (dd-java-agent 1.56.0 and 1.66.0; Armeria 1.33.4 and 1.41.0). An agent-less client sends baggage: jtbd=ap.curl,user.id=u1 plus x-datadog-* headers to a relay server, whose handler logs Baggage.current() and makes one outbound OkHttp call:
| relay server | Baggage.current() in handler (OTel bridge on) |
baggage header on the relay's outbound call |
baggage.jtbd tag on server span |
trace joins |
|---|---|---|---|---|
Armeria GrpcService |
{} |
none | yes | yes |
| Jetty 11 servlet | {jtbd=ap.curl, user.id=u1} |
jtbd=ap.curl,user.id=u1 |
yes | yes |
The result was the same with the OTel bridge unset, apart from the Baggage.current() column, which the bridge feeds. I did not run a grpc-java (Netty) server in that harness. For grpc-1.5, the unit test below reproduces the same loss.
Other callers of the deprecated helper (master at 02d50d2, non-test code). I found these by reading the code and have not reproduced them. They look like they have the same shape: extract, keep only the span context, then activate a span-only context.
- RPC:
sofarpc-5.0(ProviderProxyInvokerInstrumentation) - Messaging consumers:
kafka-clients-0.11andkafka-clients-3.8(TracingIterator),aws-java-sqs-1.0andaws-java-sqs-2.0(TracingIterator),javax-jms-1.1(JMSMessageConsumerInstrumentation,DatadogMessageListener),rabbitmq-amqp-2.7(RabbitDecorator),google-pubsub-1.116(PubSubDecorator) - API shims:
opentracing-0.31/0.32(OTTracer),opentelemetry-0.3(OtelContextPropagators)
I've seen #11286 and the note there that W3C baggage was initially scoped to HTTP. gRPC carries baggage as an HTTP/2 header, and these servers already extract and tag it, so it seemed worth reporting on its own. Please relabel as a feature request if that fits your conventions better.
Expected Behavior
When a gRPC server span is started from extracted headers, the rest of the extracted context (W3C baggage) is current for the whole call, as it is for HTTP servers. In particular:
Baggage.current()in the service implementation returns the inbound members.- Outbound calls made from the handler re-inject the
baggageheader.
Reproduction Code
Minimal Spock test against grpc-1.5. The same shape against an Armeria GrpcService fails the same way.
class GrpcServerBaggageTest extends InstrumentationSpecification {
def "inbound baggage is current in unary handler"() {
setup:
Map<String, String> seen = null
def greeter = new GreeterGrpc.GreeterImplBase() {
@Override
void sayHello(Helloworld.Request req, StreamObserver<Helloworld.Response> obs) {
seen = Baggage.fromContext(Context.current())?.asMap()
obs.onNext(Helloworld.Response.newBuilder().setMessage("hi").build())
obs.onCompleted()
}
}
def name = InProcessServerBuilder.generateName()
def server = InProcessServerBuilder.forName(name).addService(greeter).directExecutor().build().start()
def md = new Metadata()
md.put(Metadata.Key.of("baggage", Metadata.ASCII_STRING_MARSHALLER), "user.id=abc123")
def channel = InProcessChannelBuilder.forName(name)
.intercept(MetadataUtils.newAttachHeadersInterceptor(md)).directExecutor().build()
when:
GreeterGrpc.newBlockingStub(channel).sayHello(Helloworld.Request.newBuilder().setName("x").build())
then:
seen == ["user.id": "abc123"] // on master: seen == null (a span is current, baggage is not)
cleanup:
channel.shutdownNow(); server.shutdownNow()
}
}
- Linguagem predominante
- Java
- Estrelas
- 738
- Forks
- 364
- Merge médio
- 2d 21h
- PRs com merge (30d)
- 228
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de DataDog/dd-trace-java
-
type: bug report
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
DataDog/dd-trace-java#12818 · 2 comentários · 7 reações ·
Mantenedores costumam responder em até 2 dias
-
Update DEFAULT_HTTP_CLIENT_ERROR_STATUSES to include 5xx status codesTalvez livre de novo Um pull request para esta issue foi fechado sem ser mesclado. Abertatype: feature request
Dificuldade 1/5 1-3 horas Facilidade para iniciantes 70/100
DataDog/dd-trace-java#10245 · 1 comentário ·
Mantenedores costumam responder em até 2 dias
-
One unretransformable class drops all instrumentation of AOT-preloaded classes when IAST or AppSec (RASP) is on (zero request spans)Talvez já em andamento @mcculls assumiu há 2 dias. Aberta
DataDog/dd-trace-java#13041 · 1 responsável ·
Mantenedores costumam responder em até 2 dias
-
dd-trace-ot 1.67.x: NoClassDefFoundError `ddtrot/dd/trace/api/llmobs/LLMObs`Talvez já em andamento @amarziali assumiu há 12 dias. Abertatype: bug report
DataDog/dd-trace-java#12857 · 1 reação · 1 responsável ·
Mantenedores costumam responder em até 2 dias
-
type: feature request
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 48/100
DataDog/dd-trace-java#12838 · 2 comentários ·
Mantenedores costumam responder em até 2 dias
Todas as issues de DataDog/dd-trace-java
Issues semelhantes
-
staticAssetsPath follows symlinks outside the directory on WindowsTalvez já em andamento @ybelMekk assumiu hoje. Abertabug security findings
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
navikt/mock-oauth2-server#1132 ·
Mantenedores costumam responder em até 1 dia
-
agent:working follow-up
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
Sanne/incus-spawn#1683 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
checkstyle/checkstyle#22210 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 67/100
google/error-prone#6239 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
[Failing Test]: BigqueryClient.queryUnflattened fails BigQuery ITs on a transient 503Talvez já em andamento @mxtymoshyk assumiu hoje. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 77/100
Mantenedores costumam responder em até 1 dia