Skip to content

Agent crash-loops with misleading 'OTEL collector not reachable / Protocol mismatch' — actually authbridge-proxy resets OTLP egress (collector missing from NO_PROXY) #34

Description

@yoavkatz

Summary

Agent pods crash-loop with a misleading "OTEL is enabled but collector is not reachable: Protocol mismatch" error. The OTEL collector is actually healthy and reachable — the real cause is that the agent's OTLP telemetry egress is forced through the authbridge-proxy sidecar, which is not configured to route the collector host and resets the connection. The exgentic library then misreports the reset ([Errno 104] Connection reset by peer) as a protocol/reachability problem, and the agent exits 1 → CrashLoopBackOff.

Symptoms

Agent container logs:

Starting Exgentic A2A Agent
Agent: tool_calling
...
Error ─────────────────────────────────────────────
 OTEL is enabled but collector is not reachable: Protocol mismatch:
 configured as HTTP but server
 http://otel-collector.kagenti-system.svc.cluster.local:8335 may be gRPC.
 Error: [Errno 104] Connection reset by peer
stream closed: EOF for team1/exgentic-a2a-tool-calling-...-parallel-1 (agent)

Pod state: CrashLoopBackOff, container agent Ready=false with repeated restarts, while sidecar authbridge-proxy is Ready=true.

Root cause

The error message is misleading — it is not a protocol mismatch and the collector is reachable.

The agent pod contains:

  • agent container — the workload (ghcr.io/exgentic/exgentic-a2a-tool_calling:latest)
  • authbridge-proxy sidecar (ghcr.io/kagenti/kagenti-extensions/authbridge:...) listening on 127.0.0.1:8081
  • proxy-init initContainer (ghcr.io/kagenti/kagenti-extensions/proxy-init:...) that configures egress through the proxy

Relevant agent env:

OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector.kagenti-system.svc.cluster.local:8335
OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf
EXGENTIC_OTEL_ENABLED:        true
HTTP_PROXY:                   http://127.0.0.1:8081
HTTPS_PROXY:                  http://127.0.0.1:8081
NO_PROXY:                     127.0.0.1,localhost

Because otel-collector.kagenti-system.svc.cluster.local is not in NO_PROXY, the OTLP HTTP exporter routes through the authbridge-proxy. The authbridge is not configured to route/authorize the collector host, so it resets the connection. The exgentic OTEL preflight check surfaces that reset as a bogus "Protocol mismatch: configured as HTTP but server may be gRPC," then the agent hard-fails and exits.

Verification that the collector itself is fine

The collector runs the OTLP HTTP receiver on port 8335 (relocated from the default 4318 via a launch flag):

/otelcol-contrib --config=/etc/otelcol-config/base.yaml \
  --set receivers::otlp::protocols::http::endpoint=0.0.0.0:8335

Probing directly (from a plain pod in kagenti-system with no proxy):

POST http://otel-collector:8335/v1/traces   -> HTTP 200   (healthy OTLP HTTP receiver)
GET  http://otel-collector:8335/             -> HTTP 404   (expected for OTLP HTTP)
GET  http://otel-collector:4317/v1/traces    -> 000        (4317 is the gRPC port, resets over HTTP)

So the endpoint URL and protocol configured on the agent are correct; the collector is reachable when the proxy is bypassed.

How to reproduce

  1. Deploy an exgentic A2A workload (e.g. exgentic-a2a-tool-calling / gsm8k) into a namespace where pods get the kagenti authbridge-proxy sidecar + proxy-init initContainer, with EXGENTIC_OTEL_ENABLED=true and OTEL_EXPORTER_OTLP_ENDPOINT pointing at the in-cluster OTEL collector on :8335.
  2. Observe the agent container crash-loop with the "collector is not reachable: Protocol mismatch" error above.
  3. Confirm the collector is actually healthy from a proxy-less pod:
    kubectl run otel-probe --rm -i --restart=Never --image=curlimages/curl -n kagenti-system -- \
      curl -s -o /dev/null -w "%{http_code}\n" -X POST \
      http://otel-collector:8335/v1/traces -H "Content-Type: application/json" -d '{}'
    # -> 200
    
  4. Confirm the collector host is not excluded from proxying:
    kubectl get pod <agent-pod> -n team1 \
      -o jsonpath='{range .spec.containers[?(@.name=="agent")].env[*]}{.name}={.value}{"\n"}{end}' \
      | grep -i proxy
    # NO_PROXY=127.0.0.1,localhost   (collector host absent)
    

Suggested fixes (any one)

  1. Add the collector to NO_PROXY so telemetry bypasses the authbridge (preferred — telemetry does not need auth-bridging):
    NO_PROXY=127.0.0.1,localhost,otel-collector.kagenti-system.svc.cluster.local,.svc.cluster.local
    
  2. Add otel-collector.kagenti-system.svc.cluster.local:8335 to the authbridge-proxy allowlist/route config if telemetry is intended to be proxied.
  3. Make the exgentic OTEL preflight non-fatal (warn instead of exit 1) and/or fix the misleading "Protocol mismatch" message so a proxy reset is reported accurately.

The env vars and sidecar injection are set by the deployment/platform layer, not by exgentic_a2a_runner (the runner only reads OTEL_EXPORTER_OTLP_ENDPOINT from the environment), so the NO_PROXY fix belongs in the workload-harness deployment tooling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions