-
Notifications
You must be signed in to change notification settings - Fork 838
Description
Which component is this bug for?
Traceloop SDK
📜 Description
When using the Traceloop SDK with a gRPC endpoint (no http:// prefix), the exporter fails with StatusCode.UNAVAILABLE even when:
- TCP connectivity to the endpoint works
- The OpenTelemetry Collector is configured to accept insecure gRPC connections
Root Cause
In traceloop/sdk/tracing/tracing.py, the init_spans_exporter function creates a GRPCExporter without setting insecure=True:
def init_spans_exporter(api_endpoint: str, headers: Dict[str, str]) -> SpanExporter:
if "http" in api_endpoint.lower() or "https" in api_endpoint.lower():
return HTTPExporter(endpoint=f"{api_endpoint}/v1/traces", headers=headers)
else:
return GRPCExporter(endpoint=f"{api_endpoint}", headers=headers) # Missing insecure=True. The OpenTelemetry `OTLPSpanExporter` (gRPC) defaults `insecure=False`, which means it attempts a TLS connection. When the collector accepts insecure connections, the TLS handshake fails.
Environment
- Traceloop SDK version: 0.49.1
- Python version: 3.12
- OpenTelemetry Collector configured with:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317 # No TLS configured
👟 Reproduction steps
- Configure Traceloop with a gRPC endpoint (no http/https prefix):
Traceloop.init(app_name="myapp", api_endpoint="otelcol.example.com:4317")
-
Run the application
-
Observe error:
Failed to export traces to otelcol.example.com:4317, error code: StatusCode.UNAVAILABLE
👍 Expected behavior
The SDK should successfully connect to collectors that accept insecure gRPC connections.
👎 Actual Behavior with Screenshots
{"level": "error", "message": "Failed to export traces to otelcol.example.svc.cluster.local:4317, error code: StatusCode.UNAVAILABLE", "time": "2025-11-27T16:10:04.348Z", "caller": "/app/.venv/lib/python3.12/site-packages/opentelemetry/exporter/otlp/proto/grpc/exporter.py:416"}
{"level": "error", "message": "Failed to export traces to otelcol.example.svc.cluster.local:4317, error code: StatusCode.UNAVAILABLE", "time": "2025-11-27T16:10:06.299Z", "caller": "/app/.venv/lib/python3.12/site-packages/opentelemetry/exporter/otlp/proto/grpc/exporter.py:416"}
{"level": "warning", "message": "Transient error StatusCode.UNAVAILABLE encountered while exporting traces to otelcol.example.svc.cluster.local:4317, retrying in 0.80s.", "time": "2025-11-27T16:10:07.077Z", "caller": "/app/.venv/lib/python3.12/site-packages/opentelemetry/exporter/otlp/proto/grpc/exporter.py:424"}
🤖 Python Version
python3.12
📃 Provide any additional context for the Bug.
Support standard gRPC URL schemes like other gRPC clients:
| Scheme | Protocol | TLS |
|---|---|---|
grpc:// |
gRPC | ❌ Insecure |
grpcs:// |
gRPC | ✅ Secure (TLS) |
def init_spans_exporter(api_endpoint: str, headers: Dict[str, str]) -> SpanExporter:
endpoint_lower = api_endpoint.lower()
if endpoint_lower.startswith("http://") or endpoint_lower.startswith("https://"):
return HTTPExporter(endpoint=f"{api_endpoint}/v1/traces", headers=headers)
elif endpoint_lower.startswith("grpc://"):
# Insecure gRPC
clean_endpoint = api_endpoint[7:] # Remove "grpc://"
return GRPCExporter(endpoint=clean_endpoint, headers=headers, insecure=True)
elif endpoint_lower.startswith("grpcs://"):
# Secure gRPC (TLS)
clean_endpoint = api_endpoint[8:] # Remove "grpcs://"
return GRPCExporter(endpoint=clean_endpoint, headers=headers, insecure=False)
else:
# No scheme: default to insecure gRPC for backward compatibility
return GRPCExporter(endpoint=api_endpoint, headers=headers, insecure=True)
This follows the standard convention used by gRPC clients across languages:
grpc://host:port→ insecure connectiongrpcs://host:port→ secure connection (TLS)
👀 Have you spent some time to check if this bug has been raised before?
- I checked and didn't find similar issue
Are you willing to submit PR?
Yes I am willing to submit a PR!