OTLP telemetry not exported in headless (-p) mode

Resolved 💬 2 comments Opened Mar 11, 2026 by johnplanow Closed Mar 11, 2026

Bug Description

Claude Code does not export OTLP telemetry data when running in headless (-p) mode. Environment variables are correctly set on the process, but no HTTP connections are made to the configured OTLP endpoint.

Environment Info

  • Platform: linux (Ubuntu, kernel 6.17.0-14-generic)
  • Version: 2.1.72 (Claude Code)
  • Node: v22.22.1

Steps to Reproduce

  1. Start an OTLP HTTP/JSON receiver on port 4318
  2. Spawn Claude Code in headless mode with OTLP env vars:
CLAUDE_CODE_ENABLE_TELEMETRY=1 \
OTEL_METRICS_EXPORTER=otlp \
OTEL_LOGS_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_PROTOCOL=http/json \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
OTEL_METRIC_EXPORT_INTERVAL=5000 \
claude -p "respond with just the word hello" --max-turns 1
  1. Monitor for TCP connections to port 4318: ss -tnp | grep 4318

Expected Behavior

Claude Code should export metrics/logs/traces to the OTLP endpoint, same as it does in interactive mode.

Actual Behavior

Zero HTTP connections are made to the OTLP endpoint. No telemetry data is exported. The OTLP receiver's access logs show no incoming requests from the Claude Code process.

Verification

  • The OTLP receiver is confirmed working (responds to curl http://localhost:4318/health and accepts manual POST payloads)
  • The env vars are confirmed present on the child process (verified via /proc/<pid>/environ)
  • The same env vars work when set in $HOME/.claude/settings.json for interactive sessions (per issue #1712)

Context

This affects orchestration tools (like substrate-ai) that spawn Claude Code as headless sub-agents and rely on OTLP telemetry for token tracking, efficiency scoring, and cost analysis. The CHANGELOG entry "Fixed tool_decision OTel telemetry event not being emitted in headless/SDK mode" suggests partial awareness of this gap.

Related

  • #1712 (OTLP config issues — resolved for interactive mode)

View original on GitHub ↗

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