Description
The ChatCompletion span created by the AI Gateway extproc is exported with an empty traceState, even when the incoming request carries a non-empty W3C tracestate header. All Envoy-native spans in the same trace (ingress, router egress) correctly preserve it — only the extproc-created span loses it.
Per the W3C Trace Context spec, received tracestate fields must be forwarded.
Root cause
In internal/tracing/tracer.go, StartSpanAndInjectHeaders() calls tracer.Start() which creates a new SpanContext with empty TraceState — the parent's value is not copied:
parentCtx := t.propagator.Extract(ctx, propagation.MapCarrier(headers))
newCtx, span := t.tracer.Start(parentCtx, spanName, opts...) // TraceState lost here
t.propagator.Inject(newCtx, carrier)
Repro steps
Send a request with both W3C trace context headers:
curl -X POST http://<gateway-host>/v1/chat/completions \
-H "traceparent: 00-ff202ab855ba97c79471312ef973f469-e859612da0706e48-01" \
-H "tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE" \
-d '{"model": "<model>", "messages": [{"role": "user", "content": "hello"}]}'
Inspect the trace in any OTLP backend — the ChatCompletion span will have traceState: "" while all Envoy spans preserve the original value.
Environment
- AI Gateway:
v0.5.0
- Envoy:
v1.36.4
- Envoy Gateway:
v1.6.3
- Go OTel SDK:
v1.39.0
- OTel propagator:
autoprop (defaults to tracecontext,baggage)
Description
The
ChatCompletionspan created by the AI Gateway extproc is exported with an emptytraceState, even when the incoming request carries a non-empty W3Ctracestateheader. All Envoy-native spans in the same trace (ingress,router egress) correctly preserve it — only the extproc-created span loses it.Per the W3C Trace Context spec, received
tracestatefields must be forwarded.Root cause
In
internal/tracing/tracer.go,StartSpanAndInjectHeaders()callstracer.Start()which creates a newSpanContextwith emptyTraceState— the parent's value is not copied:Repro steps
Send a request with both W3C trace context headers:
Inspect the trace in any OTLP backend — the
ChatCompletionspan will havetraceState: ""while all Envoy spans preserve the original value.Environment
v0.5.0v1.36.4v1.6.3v1.39.0autoprop(defaults totracecontext,baggage)