Skip to content

[API] Fix TraceState::Set() appending a duplicate instead of overwriting - #4610

Closed
om7057 wants to merge 2 commits into
open-telemetry:mainfrom
om7057:fix/trace-state-set-overwrite
Closed

om7057 wants to merge 2 commits into
open-telemetry:mainfrom
om7057:fix/trace-state-set-overwrite

Conversation

@om7057

@om7057 om7057 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Fixes #4583

Changes

TraceState::Set() always allocated room for and appended a new entry, even when the given key already existed in the list. Per the W3C trace-context spec, "only one entry per key is allowed", and vendors must overwrite their entry on reentry, but Set() never checked for an existing entry before appending, so calling it repeatedly with the same key just kept adding duplicates.

Two visible effects, both matching the issue:

  • ToHeader() emits the same key more than once, which is not a valid trace-context header.
  • Once enough duplicate entries accumulate, kMaxKeyValuePairs is reached and any later, genuinely new key gets silently dropped, even though the list logically has room.

The fix checks whether the key already exists first: an update reuses the existing slot (list size does not grow), and the stale entry for that key is skipped when copying the remaining entries over, so the list only ever holds one entry per key. The already-documented "list full" behavior for a real new key is unchanged.

Added TraceStateTest.TraceStateSetOverwritesExistingKey, which sets the same key many times past kMaxKeyValuePairs and checks both that the value is updated and that a subsequent distinct key can still be added afterward. Confirmed it fails against the pre-fix code (it fills up with 30 duplicate entries and the new key gets dropped) and passes after the fix.

  • CHANGELOG.md updated for non-trivial changes
  • Unit tests have been added
  • Changes in public API reviewed

Set() always appended a new entry, even when the key already existed,
rather than overwriting it in place as required by the W3C trace-context
spec ("only one entry per key is allowed"). Repeated Set() calls on the
same key duplicated the entry every time, filling kMaxKeyValuePairs with
stale copies of one key and silently dropping any later, genuinely new
key once the limit was reached.

Now checks whether the key already exists before allocating: an update
never grows the list, and the stale entry for that key is skipped when
copying the rest over, so the list only ever holds one entry per key.

Fixes open-telemetry#4583
@om7057
om7057 requested a review from a team as a code owner September 20, 2026 14:50
@marcalff

Copy link
Copy Markdown
Member

@om7057

Thanks, but this is duplicated effort with #4586.

When working on an issue like #4583, you can check in the issue page, just below the title, if there is a PR already associated with it (hint: saying "Fixes #number" in the PR automatically links the issue).

cc @dbarker

@om7057

om7057 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

You're right, my mistake for overlooking. I didn't check for a linked PR before starting. Closing this in favor of #4586.

@om7057 om7057 closed this Sep 20, 2026
@om7057
om7057 deleted the fix/trace-state-set-overwrite branch September 20, 2026 15:11
@codecov

codecov Bot commented Sep 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.52%. Comparing base (01dfc71) to head (391012c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4610      +/-   ##
==========================================
+ Coverage   86.51%   86.52%   +0.02%     
==========================================
  Files         525      525              
  Lines       20464    20468       +4     
==========================================
+ Hits        17702    17708       +6     
+ Misses       2762     2760       -2     
Files with missing lines Coverage Δ
api/include/opentelemetry/trace/trace_state.h 98.93% <100.00%> (+0.05%) ⬆️

... and 1 file with indirect coverage changes

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

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.

[API] TraceState::Set does not overwrite existing entries

2 participants