open-telemetry / open-telemetry/opentelemetry-python
W3C Baggage propagator uses form encoding instead of percent encoding
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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