OTEL env vars from settings.json leak into Bash tool subprocesses

Resolved 💬 3 comments Opened Mar 16, 2026 by lyao-77 Closed Mar 20, 2026

Problem

When OTEL environment variables are configured in settings.json (or managed settings), they are inherited by all child processes spawned by the Bash tool. This causes user applications to inadvertently initialize OpenTelemetry exporters and attempt to connect to localhost:4317.

Reproduction

  1. Configure OTEL telemetry in ~/.claude/settings.json:
{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp"
  }
}
  1. Ask Claude to run any application that uses an OTel-aware framework (Java Spring, Python Flask, Go, Node.js):
run: go test ./...
run: npm test
run: python main.py
  1. The user's application sees OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 in its environment and auto-initializes an OTLP exporter, causing:
  • Connection errors if no collector is running on :4317
  • Telemetry pollution if a collector IS running (user app telemetry mixed with Claude Code telemetry)

Impact

This is especially problematic for enterprise deployments where OTEL settings are pushed via managed settings (macOS managed preferences). Users cannot remove the variables themselves, and every Bash tool invocation leaks the OTEL config into their applications.

Many OTel SDKs (Java, Python, Go, Node.js) auto-configure when they detect OTEL_EXPORTER_OTLP_ENDPOINT — no code changes needed. This makes the env var leakage silently break or pollute user applications.

Proposed Solution

Claude Code should **not propagate its own OTEL_ env vars* to child processes spawned by the Bash tool. These variables are meant to configure Claude Code's internal telemetry, not user applications.

Options (in order of preference):

  1. **Strip OTEL_ vars from Bash tool subprocess environment* — Claude Code reads the OTEL config at startup; child processes don't need them. This is the simplest and most correct fix.
  1. Support env.exclude patterns in settings — Allow settings like:
{
  "env": {
    "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317"
  },
  "envExcludeFromSubprocesses": [
    "OTEL_*",
    "CLAUDE_CODE_ENABLE_TELEMETRY"
  ]
}
  1. Support file-based OTel config — Instead of env vars, allow OTEL to be configured via a dedicated settings key that doesn't touch the environment at all:
{
  "telemetry": {
    "endpoint": "http://localhost:4317",
    "protocol": "grpc",
    "metricsExporter": "otlp"
  }
}

Workaround Attempted

We tried using a SessionStart hook with CLAUDE_ENV_FILE to unset the OTEL vars, but could not get hooks to fire (separate issue).

Related

  • #7099 — Feature request for granular shell environment policy (auto-closed, same root cause)
  • Claude Code monitoring docs — documents the OTEL env var configuration

View original on GitHub ↗

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