TraceContextTextMapPropagator injects invalid traceparent header (all zeros) when SpanContext is invalid
维护者通常 2 天内回复
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 82/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- python
调研方向
从 opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py 开始,重现 issue 中的无效 SpanContext 示例。检查报告中提到的 propagator 以及 B3MultiFormat、B3SingleFormat 和 JaegerPropagator 的相关 guard。完成的标准是:无效 context 既不注入 traceparent,也不注入 tracestate,而有效 context 仍能正常传播。
由索引模型根据 Issue 内容生成。
描述
Describe your environment
- OS: Linux / macOS
- Python version: 3.10+
- SDK version: main (1.37.0.dev0)
- API version: main (1.37.0.dev0)
What happened?
In TraceContextTextMapPropagator.inject, the propagator guards against injecting invalid contexts by checking:
if span_context == trace.INVALID_SPAN_CONTEXT:
return
Because SpanContext is a tuple consisting of (trace_id, span_id, is_remote, trace_flags, trace_state, is_valid) and INVALID_SPAN_CONTEXT is statically defined with is_remote=False, trace_flags=0, and trace_state=DEFAULT_TRACE_STATE, any invalid SpanContext (i.e. where is_valid is False) that has:
is_remote=True- non-zero
trace_flags(such asTraceFlags.SAMPLED) - or non-empty
trace_state
evaluates span_context == trace.INVALID_SPAN_CONTEXT to False.
As a consequence, the guard fails to trigger and inject() proceeds to format and inject an illegal traceparent header containing all zeroes into outbound network requests:
traceparent: 00-00000000000000000000000000000000-0000000000000000-00
This violates:
- W3C Trace Context Specification: Section 3.2.2.3 forbids all-zero
trace-idandparent-id, and Section 4.2 states an implementation MUST NOT forward an invalidtraceparent. - OpenTelemetry Specification (TraceContext Propagator): "If the SpanContext is invalid, the propagator MUST NOT inject anything into the carrier."
Strict reverse proxies, service meshes (Envoy), API gateways, and downstream microservices may reject HTTP requests with invalid W3C headers with 400 Bad Request or drop the context.
Steps to Reproduce
from opentelemetry import trace
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry.trace.span import NonRecordingSpan, SpanContext
propagator = TraceContextTextMapPropagator()
# An invalid remote span context (e.g. from an upstream call)
invalid_span_context = SpanContext(trace_id=0, span_id=0, is_remote=True)
print("is_valid:", invalid_span_context.is_valid) # False
print("== INVALID_SPAN_CONTEXT:", invalid_span_context == trace.INVALID_SPAN_CONTEXT) # False
carrier = {}
ctx = trace.set_span_in_context(NonRecordingSpan(invalid_span_context))
propagator.inject(carrier, ctx)
print("Injected carrier:", carrier)
Expected Result
No traceparent or tracestate header should be injected when span_context.is_valid is False:
Injected carrier: {}
Actual Result
An illegal all-zero traceparent header is injected onto the carrier:
Injected carrier: {'traceparent': '00-00000000000000000000000000000000-0000000000000000-00'}
Additional context
The fix is straightforward. Replace the equality comparison against trace.INVALID_SPAN_CONTEXT with a check on the is_valid property:
diff --git a/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py b/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py
--- a/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py
+++ b/opentelemetry-api/src/opentelemetry/trace/propagation/tracecontext.py
@@ -81,7 +81,7 @@ class TraceContextTextMapPropagator(textmap.TextMapPropagator):
"""
span = trace.get_current_span(context)
span_context = span.get_span_context()
- if span_context == trace.INVALID_SPAN_CONTEXT:
+ if not span_context.is_valid:
return
traceparent_string = f"00-{format_trace_id(span_context.trace_id)}-{format_span_id(span_context.span_id)}-{span_context.trace_flags:02x}"
setter.set(carrier, self._TRACEPARENT_HEADER_NAME, traceparent_string)
(Note: The same span_context == trace.INVALID_SPAN_CONTEXT pattern is also present in B3MultiFormat, B3SingleFormat, and JaegerPropagator.)
- 主要语言
- Python
- 星标
- 2.7k
- 派生
- 1k
- 平均合并
- 3 天 18 小时
- 30 天内合并 PR
- 47
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
open-telemetry/opentelemetry-python 的其他 Issue
-
W3CBaggagePropagator.extract ignores all but the first baggage header可能已有人在做 @knowprasad 于 4 天前认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 78/100
open-telemetry/opentelemetry-python#5811 ·
维护者通常 2 天内回复
-
Delta exponential histogram never goes back to the maximum scale after a wide-range interval可能已有人在做 @inchang-ing 于 27 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 88/100
open-telemetry/opentelemetry-python#5716 ·
维护者通常 2 天内回复
-
难度 1/5 1 小时以内 新手友好度 70/100
open-telemetry/opentelemetry-python#5700 · 1 条评论 ·
维护者通常 2 天内回复
-
Tests in test_metric_reader_storage.py assert on process-global mock state instead of on the storage under test可能已有人在做 @ocelotl 于 49 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 88/100
open-telemetry/opentelemetry-python#5638 ·
维护者通常 2 天内回复
-
`SpanProcessor.on_end` exceptions escape cleanup and replace application exceptions可能已有人在做 @somuai 于 52 天前认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 84/100
open-telemetry/opentelemetry-python#5624 ·
维护者通常 2 天内回复
查看 open-telemetry/opentelemetry-python 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
btclib-org/btclib-wallet#587 · 1 条评论 ·
维护者通常 1 天内回复
-
documentation
难度 2/5 1-3 小时 新手友好度 68/100
Judgment-Pack/judgment-pack-spec#275 ·
维护者通常 1 天内回复
-
ai-generated
难度 2/5 1-3 小时 新手友好度 77/100
维护者通常 1 天内回复
-
documentation good first issue priority: low size: XS
难度 1/5 1-3 小时 新手友好度 92/100
yeongseon/azure-functions-doctor-python#651 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 65/100
Changaco/python-libarchive-c#146 ·