[BUG] OTEL_RESOURCE_ATTRIBUTES with raw non-ASCII (Korean) values silently drops all telemetry — bundled @opentelemetry/resources is outdated

Resolved 💬 1 comment Opened May 4, 2026 by vidam-io Closed Jun 1, 2026

Issue draft for anthropics/claude-code

Title: [BUG] OTEL_RESOURCE_ATTRIBUTES with raw non-ASCII (Korean) values silently drops all telemetry — bundled @opentelemetry/resources is outdated

Labels: bug (auto)

---

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

When OTEL_RESOURCE_ATTRIBUTES contains a raw (un-percent-encoded) non-ASCII value such as Korean, no telemetry records reach the OTLP collector for that run — not just the offending attribute. The collector receives zero records.

(Whether claude-code skips the export call entirely or sends something that the collector then drops is not directly verified — only the end observation "collector receives nothing" is confirmed.)

There is no warning, error message, or stderr output. The only visible symptom is missing data on the collector side.

Percent-encoding the same value (%ED%95%9C%EA%B8%80%ED%8C%80 instead of 한글팀) makes telemetry flow normally and the value is decoded back to Korean on the collector side. So the data path itself works; the failure happens at env-var parsing inside the bundled @opentelemetry/resources SDK.

Root cause confirmed: the version of @opentelemetry/resources bundled into claude-code 2.1.116 is the old "strict" line (≤ v2.5.1), which performs W3C Baggage octet validation and rejects any character outside 0x210x7E. This was removed in open-telemetry/opentelemetry-js#6261, released in @opentelemetry/resources v2.6.0 (2026-03-03). claude-code's package.json declares "@opentelemetry/resources": "^2.0.0", but the lockfile/bundle is pinned to a pre-fix version.

What Should Happen?

Bump the bundled @opentelemetry/resources to ≥ v2.6.0 (current latest is v2.7.1, released 2026-04-29). This single dependency bump removes the strict octet validation and allows raw non-ASCII values to pass through, matching the behavior of all other OTel SIGs.

Secondary asks:

  • Document the percent-encoding requirement for OTEL_RESOURCE_ATTRIBUTES (until the bump ships, this is the only workaround).
  • Even after the bump, parsing errors are still logged at diag.debug (invisible at default log level) — this is an upstream concern but worth surfacing as a warning at the claude-code layer for env-var misconfigurations.

Error Messages/Logs

(none — failure is silent at default log level; SDK uses diag.debug which is suppressed)

Steps to Reproduce

  1. Start a local OTLP collector (e.g. otelcol-contrib 0.150.1) on :4317/:4318 with a debug exporter (verbosity detailed).
  1. Run claude with raw Korean in OTEL_RESOURCE_ATTRIBUTES:

``bash
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_RESOURCE_ATTRIBUTES="team=한글팀,case=raw"
claude --print "hello"
``
→ Collector receives 0 records.

  1. Repeat with percent-encoded value:

``bash
export OTEL_RESOURCE_ATTRIBUTES="team=%ED%95%9C%EA%B8%80%ED%8C%80,case=pct"
claude --print "hello"
`
→ Collector receives normally;
-> team: Str(한글팀)` appears in debug output.

The only difference between cases is whether raw UTF-8 bytes are present in the env-var value.

Investigation summary

1. Bundled SDK identified as pre-#6261 (strict)

The minified claude-code 2.1.116 binary still contains the function name _isBaggageOctetString and _parseResourceAttributes:

$ strings /opt/homebrew/Caskroom/claude-code/2.1.116/claude | grep -oE '_isBaggageOctet[^,;)]{0,200}' | head
_isBaggageOctetString(H
_isBaggageOctetString(H

_isBaggageOctetString is the strict W3C Baggage octet check that was deleted by PR #6261. Its presence in the bundle means the locked @opentelemetry/resources is from the strict line — i.e. ≤ v2.5.1 (last release before #6261).

package.json declares "@opentelemetry/resources": "^2.0.0", so the lockfile (or bundling pin) is what's stuck on the old line. A re-resolve at build time would pick up v2.7.x.

2. Standalone repro confirms strict v2.5.1 behavior matches the observed drop

Verbatim port of v2.5.1 EnvDetector parsing logic (source) run on the same inputs:

| Input | v2.5.1 (strict, what claude-code uses) | v2.7.1 (post-#6261, current main) |
|---|---|---|
| team=한글팀,case=raw | {} (silent drop) | {team:'한글팀', case:'raw'} |
| team=%ED%95%9C...,case=pct | {team:'한글팀', case:'pct'} | same |
| team=%ZZ | {} (URI malformed) | {} (URI malformed) |
| team=mlops,env=prod | {team:'mlops', env:'prod'} | same |

The strict-line drop on raw Korean exactly reproduces the silent failure observed in claude-code.

3. Other failure points ruled out

  • macOS shell → Node process.env: Korean UTF-8 preserved intact across LANG=C, LANG=ko_KR.UTF-8, and unset.
  • decodeURIComponent('한글팀') does not throw.
  • sanitizeAttributes and OTLP toAnyValue transformer in current main have no ASCII-only checks.

So the failure is unambiguously at the bundled-SDK env-var parsing stage.

Related upstream context

Workaround (until the bump ships)

Pre-encode attribute values:

python3 -c "import urllib.parse; print(urllib.parse.quote('한글팀'))"
# %ED%95%9C%EA%B8%80%ED%8C%80

Or via ~/.claude/settings.json:

{
  "env": {
    "OTEL_RESOURCE_ATTRIBUTES": "team=%ED%95%9C%EA%B8%80%ED%8C%80,env=prod"
  }
}

Is this a regression?

I don't know — depends on whether any prior claude-code release ever bundled @opentelemetry/resources ≥ v2.6.0.

Last Working Version

(unknown)

Claude Code Version

2.1.116 (Claude Code)

Build: 2026-04-20T13:57:26Z, GIT_SHA: 9e176d0

Platform

Anthropic API

Operating System

macOS (arm64, Darwin 23.6.0)

Terminal/Shell

iTerm2 (zsh) — not terminal-specific, reproducible across terminals.

Additional Information

  • Local collector config: standard otlp receiver → batch processor → debug exporter (verbosity: detailed).
  • Documentation improvement (separate concern but related): the docs for OTEL_RESOURCE_ATTRIBUTES should call out the percent-encoding requirement and the silent-drop risk for raw non-ASCII values, at least until the SDK bump lands.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗