[BUG] `env` block in managed-settings.json does not apply OTEL env vars — initialization order issue

Open 💬 3 comments Opened Jun 11, 2026 by dominicbalabat

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Summary

env keys in /Library/Application Support/ClaudeCode/managed-settings.json do not take effect for OpenTelemetry configuration. The OTEL SDK initializes before managed settings are read, so OTEL-related env vars set via the env block arrive too late.

Environment

Claude Code: 2.1.170 (desktop-bundled) / 2.1.173 (system)
Desktop app: 1.11847.5
OS: macOS darwin 25.5.0 arm64
Deployment: MDM-managed enterprise
Managed settings file

Path: /Library/Application Support/ClaudeCode/managed-settings.json
Permissions: -rw-r--r-- root wheel ✓

{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://<collector>",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer <token>",
"OTEL_LOG_TOOL_DETAILS": "1"
}
}
How the desktop app spawns the CLI (ps aux):

claude \
--setting-sources=user,project,local \
--settings {} \
...
managed is absent from --setting-sources; --settings {} is empty.

Root cause

The desktop app sets OTEL env vars at the OS level before exec'ing the CLI:

OTEL_SERVICE_NAME=claude-code-desktop
OTEL_RESOURCE_ATTRIBUTES=service.name=claude-code-desktop,...
The Node.js OTEL SDK initializes at module load using these OS-level vars. When the CLI later reads managed-settings.json and does process.env.OTEL_EXPORTER_OTLP_ENDPOINT = "...", the SDK is already initialized — the value has no effect.

The --setting-sources help text says "Admin-managed (policy) settings still apply" but lists only auth, model selection, and built-in tools — not the env block.

What Should Happen?

Expected behavior:

Managed-settings env vars are applied before OTEL SDK initialization so enterprise deployments can route telemetry via MDM without OS-level launchd injection.

Error Messages/Logs

No error is surfaced. The failure is silent.

# Verify managed settings file is present and readable
$ ls -la "/Library/Application Support/ClaudeCode/managed-settings.json"
-rw-r--r--  1 root  wheel  391 Jun 11 11:48 managed-settings.json

# File parses as valid JSON — no error
$ python3 -c "import json; json.load(open('/Library/Application Support/ClaudeCode/managed-settings.json')); print('valid')"
valid

# Spawned CLI process environment — OTEL vars from managed-settings.json are absent
$ ps eww -p <claude-pid> | tr ' ' '\n' | grep -E "OTEL|CLAUDE_CODE_ENABLE"
OTEL_SERVICE_NAME=claude-code-desktop
OTEL_RESOURCE_ATTRIBUTES=service.name=claude-code-desktop,service.version=1.11847.5,...
# ^ Only desktop app's own OTEL vars. No OTEL_EXPORTER_OTLP_* or CLAUDE_CODE_ENABLE_TELEMETRY.

# Attempting to use 'managed' as a --setting-sources value confirms it is not a recognized source
$ claude --setting-sources=managed --print "test"
Error processing --setting-sources: Invalid setting source: managed. Valid options are: user, project, local
No OTEL initialization logs appear. No telemetry reaches the configured collector endpoint. No warning or error is logged to indicate that env vars from managed-settings.json were ignored.

Steps to Reproduce

  1. Deploy managed-settings.json via MDM to /Library/Application Support/ClaudeCode/managed-settings.json with the following content:

{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://<your-collector>",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer <token>",
"OTEL_LOG_TOOL_DETAILS": "1"
}
}
Permissions: -rw-r--r-- root wheel (world-readable)

  1. Launch the Claude Code desktop app (v1.11847.5, macOS).
  2. Start any conversation to trigger a CLI subprocess spawn.
  3. Observe the spawn command via ps aux | grep claude:

.../claude-code/2.1.170/.../claude \
--setting-sources=user,project,local \
--settings {} \
...
Note: managed is absent from --setting-sources; --settings is empty {}.

  1. Inspect the spawned process environment:

ps eww -p <claude-pid> | tr ' ' '\n' | grep -E "OTEL|CLAUDE_CODE_ENABLE_TELEMETRY"
Observed: Only OTEL_SERVICE_NAME=claude-code-desktop and OTEL_RESOURCE_ATTRIBUTES=... (set by the desktop app itself). None of the OTEL_EXPORTER_OTLP_* vars or CLAUDE_CODE_ENABLE_TELEMETRY from managed-settings.json are present.
6.Verify the managed-settings file is readable and valid:cat "/Library/Application Support/ClaudeCode/managed-settings.json" # parses OK
python3 -c "import json; json.load(open('/Library/Application Support/ClaudeCode/managed-settings.json')); print('valid')"

  1. Confirm no telemetry reaches the configured OTEL endpoint (zero accepted log records / metric points on collector side).

Expected: OTEL env vars from managed-settings.json env block are applied before OTEL SDK initialization; telemetry is sent to the configured endpoint.

Actual: OTEL SDK initializes using only the desktop app's own env vars. Managed-settings env vars are applied after SDK init and have no effect.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.173 (system CLI) / 2.1.170 (desktop-bundled CLI that actually runs during sessions).

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Version discrepancy: The desktop app bundles and spawns its own CLI (claude-code/2.1.170) rather than the system-installed CLI (2.1.173). Both versions exhibit the same behavior.

managed is not a valid --setting-sources value: Running claude --setting-sources=managed returns Invalid setting source: managed. Valid options are: user, project, local. This confirms managed settings are loaded through a separate code path — but that path does not apply the env block before OTEL SDK initialization.

The desktop app has a parallel enterprise config channel: The renderer process receives --desktop-enterprise-config={"disableEssentialTelemetry":false,"disableNonessentialTelemetry":false,...} as a CLI flag. This suggests the desktop app has its own enterprise settings pipeline that is distinct from managed-settings.json. It is unclear whether env keys from managed-settings.json are ever intended to flow through this channel.

Related open issues: This appears to be the same root cause as #66401 (macOS, TUI) and #67339 (Windows Desktop), where OTEL env vars set via settings files are confirmed read but produce no telemetry output.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗