Skip to content

Fix BaggageBuilder.put() silently accepting empty string keys - #8660

Merged
jack-berg merged 3 commits into
open-telemetry:mainfrom
itsmehotpants:fix/baggage-builder-empty-key-validation
Aug 22, 2026
Merged

Fix BaggageBuilder.put() silently accepting empty string keys#8660
jack-berg merged 3 commits into
open-telemetry:mainfrom
itsmehotpants:fix/baggage-builder-empty-key-validation

Conversation

@itsmehotpants

Copy link
Copy Markdown
Contributor

Problem

The W3C Baggage spec requires that a baggage-name be a non-empty token (§3 definition). An empty string "" is therefore an invalid key and should be silently ignored, the same way null keys already are.

Currently, ImmutableBaggage.Builder.put() accepts empty string keys and stores them. When the W3CBaggagePropagator later serialises the Baggage into a header, it includes the empty-key entry, which can produce malformed baggage headers like:

baggage: =somevalue, valid-key=other

This corrupts propagation for downstream services.

Inconsistency with the propagator

The parsing path (W3CBaggagePropagator.isValidBaggageKey) already correctly rejects empty/blank keys when reading incoming headers:

// W3CBaggagePropagator.java
private static boolean isValidBaggageKey(String name) {
  return name != null && !name.trim().isEmpty() && StringUtils.isPrintableString(name);
}

This PR closes the same gap on the programmatic builder path.

Change

  • ImmutableBaggage.Builder.put(): add key.isEmpty() to the existing early-return null-guard
  • BaggageBuilder.java: document the empty-key contract in Javadoc (links W3C spec)
  • ImmutableBaggageTest: correct the existing put_keyEmpty test (it was asserting the buggy behaviour); add put_keyEmpty_withMetadata variant

Fixes #8657

Per the W3C Baggage spec (§3 definition), a baggage-name must be a
non-empty token. An empty string key is therefore invalid and should
be ignored, not stored and later propagated downstream.

The W3CBaggagePropagator.isValidBaggageKey() already correctly
rejects empty keys when *parsing* incoming headers. This change
closes the same gap on the *programmatic* builder path so that
calling Baggage.builder().put("", value).build() is a no-op,
consistent with how null keys are handled today.

- ImmutableBaggage.Builder.put(): add key.isEmpty() guard
- BaggageBuilder.java: document the empty-key contract in Javadoc
- ImmutableBaggageTest: correct put_keyEmpty to assert the right
  behaviour; add put_keyEmpty_withMetadata variant

Fixes open-telemetry#8657
@itsmehotpants
itsmehotpants requested a review from a team as a code owner July 25, 2026 07:58
@linux-foundation-easycla

linux-foundation-easycla Bot commented Jul 25, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: itsmehotpants / name: itsmehotpants (a669383)

@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Jul 25, 2026

Copy link
Copy Markdown

Pull request dashboard status

Merged · refreshed 2026-08-22 02:33 UTC

Status above doesn't look right?
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.28%. Comparing base (b421aed) to head (54a9dec).

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #8660   +/-   ##
=========================================
  Coverage     91.28%   91.28%           
+ Complexity    10473    10472    -1     
=========================================
  Files          1006     1006           
  Lines         28277    28277           
  Branches       3569     3569           
=========================================
  Hits          25812    25812           
  Misses         1674     1674           
  Partials        791      791           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Override
public BaggageBuilder put(String key, String value, BaggageEntryMetadata entryMetadata) {
if ((key == null) || (value == null) || (entryMetadata == null)) {
if ((key == null) || key.isEmpty() || (value == null) || (entryMetadata == null)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

isEmpty() only checks for an empty string, but doesn't account for whitespace. According to the spec, a key cannot consist solely of whitespace, so maybe isBlank() should be used instead?

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.

isBlank was added in java 11. Would also need to go further and confirm there are printable chars as well. I'm going to merge without resolving this - feel free to open a separate issue / pr to track.

@opentelemetry-pr-dashboard

This comment has been minimized.

@jack-berg
jack-berg merged commit 35636ae into open-telemetry:main Aug 22, 2026
52 of 54 checks passed
@otelbot

otelbot Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Thank you for your contribution @itsmehotpants! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this survey.

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.

Fix: BaggageBuilder.put() accepts empty string keys instead of ignoring them

3 participants