open-telemetry / open-telemetry/opentelemetry-python

W3C Baggage propagator uses form encoding instead of percent encoding

Open Beginner friendly
#5,566 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
4d 15h
Merged PRs (30d)
19

Description

Describe your environment

Labels: bug, api, propagator, spec-compliance
Affected packages: opentelemetry-api
Found on: main @ 0a5d76b6
Environment: CPython 3.12

What happened?

W3CBaggagePropagator encodes and decodes baggage with quote_plus / unquote_plus, which is application/x-www-form-urlencoded. That form maps a space to + and decodes + back to a space. The W3C Baggage grammar defines baggage-octet as %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E, so + (%x2B) is an ordinary literal that must be preserved, and SP (%x20) is excluded and must be percent-encoded as %20.

Both directions are wrong, and neither raises: values are silently corrupted as they cross a service boundary.

Steps to Reproduce
from opentelemetry.baggage import get_all, set_baggage
from opentelemetry.baggage.propagation import W3CBaggagePropagator

p = W3CBaggagePropagator()

# extract: a compliant peer sends a literal "+"
print(dict(get_all(p.extract({"baggage": "key=a+b"}))))

# inject: a value containing a space
carrier = {}
p.inject(carrier, context=set_baggage("key", "a b"))
print(carrier)
Expected Result

extract of key=a+b yields {'key': 'a+b'}, and inject of a value containing a space emits key=a%20b.

Actual Result
{'key': 'a b'}          # extract corrupted "a+b" into "a b"
{'baggage': 'key=a+b'}  # inject emitted "+" where %20 is required

# further extract cases
wire 'key=+'      -> ''       (value destroyed entirely)
wire 'key=c++'    -> 'c'      (trailing strip() eats the rest)
wire 'key=a+b+c'  -> 'a b c'
Additional context

Silent data corruption at service boundaries in any polyglot deployment. Baggage commonly carries tenant identifiers, routing keys and feature flags, so a corrupted value can misroute a request rather than merely degrade telemetry. OpenTelemetry implementations in other languages percent-encode, so the corruption only appears when Python talks to a non-Python peer - which makes it hard to spot in a single-language test environment.

Would you like to implement a fix?

Yes

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the W3CBaggagePropagator entry point in the affected opentelemetry-api package and reproduce the extract and inject examples from this issue. Check the quote_plus/unquote_plus handling against the W3C Baggage grammar, then verify that literal '+' is preserved and spaces are represented as %20 in both directions.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.