[BUG] remote-settings.json env keys silently ignored when ~/.claude/settings.json also defines env
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?
When both ~/.claude/remote-settings.json (server-managed, delivered from the Claude.ai admin console) and ~/.claude/settings.json (user) define an env block, the local env block wins wholesale and any keys present only in remote-settings.json are silently dropped. This is the opposite of documented precedence (settings, admin-setup), which states managed/server settings are the highest priority tier.
Specifically, env is not deep-merged — only permissions.allow / permissions.deny are documented as merging across scopes. So if env keys are split across scopes, the lower-priority scope's whole object replaces the higher-priority one (or some equivalent failure mode), with no warning.
Concrete repro from my setup (OTel telemetry):
Admin console push → ~/.claude/remote-settings.json:
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel-collector-stg.example.internal:443",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer <REDACTED>",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_METRICS_INCLUDE_VERSION": "true"
}
}
Local ~/.claude/settings.json (same keys except OTEL_EXPORTER_OTLP_HEADERS):
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel-collector-stg.example.internal:443",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_METRICS_INCLUDE_VERSION": "true"
}
}
Result: OTLP exporter connects to the endpoint but sends no Authorization header. The collector (configured to require the bearer header) drops all requests. No warning, no log, no /status indication that an env key was suppressed.
Fix: I manually copied OTEL_EXPORTER_OTLP_HEADERS into ~/.claude/settings.json. Data appeared in the collector immediately, confirming the local env block had wholly shadowed the remote one.
What Should Happen?
Either:
envfromremote-settings.jsonshould win per documented precedence (managed > user), ORenvobjects should deep-merge across scopes (per-key), like a sensible config-layering system, OR- At minimum, surface a warning when
envkeys are dropped due to scope conflict, and document the actual merge behavior in the settings docs.
Option 2 is most ergonomic for orgs that want to push shared config (endpoint, auth) from the console while letting devs override individual keys locally.
Error Messages/Logs
# No errors surfaced in the Claude Code session.
# OTel collector logs (sanitized) showed unauthenticated requests being rejected:
# "msg":"auth failed","error":"missing Authorization header"
# until OTEL_EXPORTER_OTLP_HEADERS was duplicated into ~/.claude/settings.json.
Steps to Reproduce
- As an admin on a Claude for Teams/Enterprise plan, push an
envblock via the admin console containing OTEL_* keys includingOTEL_EXPORTER_OTLP_HEADERS. - Wait for
~/.claude/remote-settings.jsonto sync on a developer machine (verify viacat ~/.claude/remote-settings.json— should contain the full env block including HEADERS). - In
~/.claude/settings.json, add anenvblock with OTEL_ keys but omit*OTEL_EXPORTER_OTLP_HEADERS. - Run any Claude Code session. Observe OTLP requests reach the collector endpoint without the Authorization header. If the collector requires the header, all telemetry is dropped.
- Add
OTEL_EXPORTER_OTLP_HEADERSto~/.claude/settings.jsonmatching the value inremote-settings.json. Data flows immediately — confirming the remoteenvwas being shadowed wholesale, not deep-merged.
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.128 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Related issues:
- #44640 — Original report (now closed) on server-managed settings from admin console not syncing to Claude Code CLI. The sync itself now works for me (
remote-settings.jsonis delivered and contains the expectedenvblock), but the merge with local user settings is broken in the way described above. Filing this as a separate bug since the surface symptom differs from the closed issue. - #46204 — OTel on managed accounts (telemetry never initializes; different symptom but same code path consumes
remote-settings.json). - #50037 —
settings.jsonenv keys silently stripped underPROVIDER_MANAGED_BY_HOST(reverse direction, same "silent env-override with no warning" pattern). - #17017 — Scope replace-vs-merge bug, applied to
permissionsarrays (same bug class — scopes don't merge as users expect).
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗