Skip to content

[API] Percent-encode spaces in Baggage::ToHeader - #4765

Open
hidingmyname wants to merge 3 commits into
open-telemetry:mainfrom
hidingmyname:baggage-encode-space-percent-4745
Open

hidingmyname wants to merge 3 commits into
open-telemetry:mainfrom
hidingmyname:baggage-encode-space-percent-4745

Conversation

@hidingmyname

Copy link
Copy Markdown

Part of #4745

Changes

Baggage::ToHeader encoded a space in keys/values as + (form-style). The W3C Baggage specification uses percent-encoding, and other OpenTelemetry implementations read + as a literal plus sign, so a value such as hello world arrived as hello+world on non-C++ receivers.

This PR changes only the encode side: a space is now emitted as %20 (it simply falls through to the existing percent-encoding branch). As noted in the issue triage, this is safe across versions because existing C++ readers already decode %20.

The decode side is intentionally unchanged: FromHeader still decodes + as a space, so headers from older C++ senders keep reading the same way. Whether to stop treating + as a space is left as a maintainer decision; I'm happy to follow up with a separate PR for that if wanted.

Tests (api/test/baggage/baggage_test.cc):

  • ValidateInjectHeader: expected headers updated from + to %20.
  • ValidateExtractHeader: still asserts + decodes to a space; added a case that %20 decodes to a space.
  • New SpaceIsPercentEncoded: Set("k", "hello world")->ToHeader() is k=hello%20world and round-trips through FromHeader.

Verification (GCC 15.3, CMake + Ninja, Debug):

  • Without the header change, the updated tests fail: baggage_test 12 passed, 2 failed (ValidateInjectHeader, SpaceIsPercentEncoded, which got k=hello+world).
  • With the change: baggage_test 14/14, baggage_propagator_test 6/6, composite_propagator_test 2/2, global_propagator_test 3/3, propagator_builders_test 11/11 passed.
  • clang-format 18 applied.
  • CHANGELOG.md updated for non-trivial changes
  • Unit tests have been added
  • Changes in public API reviewed

Baggage::ToHeader encoded a space as '+' (form-style), which the W3C
Baggage specification does not define; other implementations read it as
a literal '+'. Encode spaces as %20 instead. Existing C++ readers already
decode %20, so this is safe across versions.

Decoding of '+' as space is intentionally left unchanged.

Part of open-telemetry#4745
@hidingmyname
hidingmyname requested a review from a team as a code owner November 5, 2026 08:08
@codecov

codecov Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.61%. Comparing base (d05c6a8) to head (a93090a).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4765      +/-   ##
==========================================
- Coverage   86.61%   86.61%   -0.00%     
==========================================
  Files         530      530              
  Lines       21169    21167       -2     
==========================================
- Hits        18333    18331       -2     
  Misses       2836     2836              
Files with missing lines Coverage Δ
api/include/opentelemetry/baggage/baggage.h 98.75% <ø> (-0.01%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mateenali66 mateenali66 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the fix.

ValidateInjectHeader and SpaceIsPercentEncoded fail with the + branch put back and pass at 7aa97087, and + still decodes as a space.

See minor comment on the CHANGELOG link.

Comment thread CHANGELOG.md Resolved
marcalff and others added 2 commits November 7, 2026 19:07

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants