[BUG] `env` block in managed-settings.json does not apply OTEL env vars — initialization order issue
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
- 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)
- Launch the Claude Code desktop app (v1.11847.5, macOS).
- Start any conversation to trigger a CLI subprocess spawn.
- 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 {}.
- 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')"
- 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.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗