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 を確認してください。無効なコンテキストが traceparent も tracestate も注入せず、有効なコンテキストが引き続き通常どおり伝播されれば完了です。
索引モデルが 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.6k
- フォーク
- 1k
- 平均マージ
- 5日 7時間
- マージ済み PR(30日)
- 27
環境構築
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
open-telemetry/opentelemetry-python のほかの issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 70/100
open-telemetry/opentelemetry-python#5700 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
open-telemetry/opentelemetry-python#5661 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
open-telemetry/opentelemetry-python#5638 ·
メンテナーはふだん 2 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
open-telemetry/opentelemetry-python#5624 ·
メンテナーはふだん 2 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
open-telemetry/opentelemetry-python#5574 · コメント 1 件 ·
メンテナーはふだん 2 日以内に返信
open-telemetry/opentelemetry-python の issue をすべて見る
似ている issue
-
namespace operations
難易度 1/5 1時間未満 初心者へのやさしさ 82/100
EclipseFdn/open-vsx.org#13573 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
collective/icalendar#1854 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
rancher/rancher-ai-agent#412 ·
メンテナーはふだん 6 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
TUDelftGeodesy/DePSI#134 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
HenriquesLab/rxiv-maker#335 ·