Open
Description
Description
parseTraceFlag
sets the sampled bit for any value whose length ≠ 1, even when the flag is invalid (e.g. Sampled=maybe
).
func parseTraceFlag(xraySampledFlag string) trace.TraceFlags {
if len(xraySampledFlag) == 1 && xraySampledFlag != "1" {
return traceFlagNone // ok: explicit “0”
}
return trace.FlagsSampled // ← bug: treats “maybe”, “foo”, “”, etc. as sampled
}
According to AWS X‑Ray header spec the only value that should map to trace.FlagsSampled
is "1"
. Any other value (including "0"
or garbage) must clear the flag.
Because of this, downstream OpenTelemetry SDKs mark spans as sampled when they should be drop‑eligible, inflating trace volume and potentially incurring unexpected cost.
Environment
- OS: any (confirmed on macOS 14 & Ubuntu 22.04)
- Architecture: amd64 & arm64
- Go version: 1.22.2
- Module:
go.opentelemetry.io/contrib/propagators/aws/xray
- Version / commit: v0.47.0 (
2e1b0bb
)
Steps To Reproduce
- Create an inbound carrier with an invalid sampled flag:
carrier := propagation.MapCarrier{ "X-Amzn-Trace-Id": "Root=1-abcdef12-1234567890abcdef12345678;" + "Parent=1234567890abcdef;" + "Sampled=maybe", } ctx := xray.Propagator{}.Extract(context.Background(), carrier) sc := trace.SpanContextFromContext(ctx)
- Check the flag:
fmt.Println(sc.IsValid(), sc.IsSampled()) // → true, **true**
- Observe that
IsSampled()
is true, even though"maybe"
is not legal.
Expected Behavior
parseTraceFlag("maybe")
(or any value other than "1"
) should return traceFlagNone
, so the extracted SpanContext
is not sampled.
Proposed fix:
func parseTraceFlag(xraySampledFlag string) trace.TraceFlags {
if xraySampledFlag == isSampled {
return trace.FlagsSampled
}
return traceFlagNone
}
This change:
- Honors the X‑Ray spec
- Prevents accidental over‑sampling
- Aligns with Otel propagator behavior for W3C
traceparent
Happy to submit a PR if this approach is acceptable.