OTEL_RESOURCE_ATTRIBUTES set via settings.json env or OS-level env var never applied to Claude Code's own OTLP export

Status Fixed / completed
Reported on v2.1.235
Maintainer reply None cached
Activity 1 comment · opened Aug 19, 2026 · closed Aug 20, 2026

OTEL_RESOURCE_ATTRIBUTES set via settings.json env or OS-level env var is never applied to Claude Code's own OTLP telemetry export

Summary

Custom OTEL_RESOURCE_ATTRIBUTES never appear on Claude Code's own outgoing claude_code.* OTLP metrics/logs, regardless of whether they are set via ~/.claude/settings.json's env key or as a real OS-level environment variable before launching claude. Only the built-in resource attributes (host.arch, os.type, os.version, service.name, service.version) are ever present. This happens while CLAUDE_CODE_ENABLE_TELEMETRY / OTEL_EXPORTER_OTLP_ENDPOINT / OTEL_EXPORTER_OTLP_HEADERS are supplied via an org-level managed policy (admin console).

According to the documentation (monitoring-usage.md, server-managed-settings.md), OTEL_RESOURCE_ATTRIBUTES is explicitly not part of the signal-transport variable group (OTEL_EXPORTER_OTLP_*) that managed settings withhold/own — it should follow normal per-key precedence and merge in regardless of managed telemetry routing. That does not match what we observe.

Environment

  • Reproduced on: Claude Code 2.1.235, Windows 10.0.19044 (also present, unconfirmed whether attempted, on 2.1.234 / Win 10.0.19042 and 2.1.138 / Win 10.0.26200 in the same fleet)
  • Telemetry pipeline: self-hosted OTel Collector (otel/opentelemetry-collector-contrib) receiving OTLP/HTTP, behind a Cloudflare Tunnel, with CLAUDE_CODE_ENABLE_TELEMETRY=1, OTEL_METRICS_EXPORTER=otlp, OTEL_LOGS_EXPORTER=otlp, OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS all supplied via managed/admin-console policy (highest-precedence settings tier).
  • Collector processors verified to NOT touch resource attributes (only a metric-name filter and one attribute upsert on a different key) — ruled out as the cause; confirmed by other built-in resource attributes (host.arch, os.type, etc.) passing through untouched.

Expected behavior

Setting OTEL_RESOURCE_ATTRIBUTES=device.id=...,git.email=...,git.name=...,department=... — via either env in ~/.claude/settings.json (user scope) or a real OS environment variable — should cause those key=value pairs to appear as resource attributes on every claude_code.* metric/log Claude Code exports, merged alongside the built-in ones.

Actual behavior

Across two independent, controlled tests, custom resource attributes never appear:

Test 1 — via ~/.claude/settings.json's env key:

  1. Wrote OTEL_RESOURCE_ATTRIBUTES into ~/.claude/settings.jsonenv.OTEL_RESOURCE_ATTRIBUTES (confirmed written correctly, value persisted, read back correctly by a manual --check).
  2. Fully quit Claude Code, relaunched (confirmed via a SessionStart hook's own log that at least 2 fresh session starts occurred after the write, ~13:21 and ~13:24 UTC).
  3. Result: 520 subsequent claude_code.* events for that account over the following ~70 minutes — 0 of 520 carried the custom resource attributes. Resource attribute set on every single event was only host.arch, os.type, os.version, service.name, service.version.

Test 2 — via genuine OS-level environment variable (bypassing settings.json entirely):

  1. In the same PowerShell session: $env:OTEL_RESOURCE_ATTRIBUTES = "device.id=...,device.hostname=...,git.email=...,git.name=...,department=..."
  2. Launched claude from that same shell.
  3. Result: new telemetry batches confirmed arriving (session was live and exporting), but again 0 events carried the custom resource attributes.

Both tests used the same attribute string and the same account. Result was identical and deterministic in both cases — 0% pass-through.

Data point of note

The value being tested (device.id=837bea303ea10bb298fadfdf7345714d1899085bb3188eefd460a7a7c6fc04be,device.hostname=w010955143,git.email=sangtt@fpt.com,git.name=W010955143\ISC-SangTT,department=QA) was verified byte-for-byte correct in ~/.claude/settings.json at the time of both tests — this is not a "value never got written" issue, it's a "written/set value never reaches the exporter" issue.

Hypothesis (unconfirmed)

Given both the settings.json-scoped and OS-level-scoped tests failed identically, the likely cause is not a settings-precedence issue but something in the OTLP resource-attribute assembly path itself — e.g. the resource attributes may be captured once at process/SDK initialization from a snapshot that predates env application, or OTEL_RESOURCE_ATTRIBUTES may be silently dropped somewhere in resource construction specifically when telemetry routing (OTEL_EXPORTER_OTLP_*) originates from managed settings. We could not confirm either root cause from the client side alone.

Impact

This blocks any workflow that relies on OTEL_RESOURCE_ATTRIBUTES to attach per-device/per-user identity metadata (device fingerprint, local git identity, team/department tags) to telemetry in an organization running Claude Code under a centrally managed OTLP endpoint — a documented, intended use case per monitoring-usage.md.

Request

Please confirm whether this is a known regression, and if so which version introduced it. Note: our controlled tests (both attempts to actually set OTEL_RESOURCE_ATTRIBUTES) were only run against 2.1.235; two other accounts on 2.1.234 and 2.1.138 in the same fleet also show only the built-in resource attributes, but we have not confirmed those accounts ever attempted to set OTEL_RESOURCE_ATTRIBUTES — that observation is not part of the reproduction, just a note in case it's useful. Happy to provide the raw OTLP JSON export files (out/telemetry.json) if useful for repro.

View original on GitHub ↗

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