OpenTelemetry Error Guide: 'unsupported protocol scheme' on OTLP/HTTP — Fix Endpoint URLs
Fix 'Post "collector:4318/v1/traces": unsupported protocol scheme ""' on OTLP/HTTP: add http:// or https:// to the exporter endpoint.
- #opentelemetry
- #observability
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
This error appears when an OTLP/HTTP exporter tries to POST telemetry to an endpoint that has no URL scheme. Go’s net/http client can only speak to a URL whose scheme is http or https; when the scheme is empty it refuses to send and returns:
traces export: Post "collector:4318/v1/traces": unsupported protocol scheme ""
A near-identical variant appears when a non-HTTP scheme (like a stray grpc://) is supplied to the HTTP exporter:
metrics export: Post "grpc://collector:4318/v1/metrics": unsupported protocol scheme "grpc"
unsupported protocol scheme "" means the endpoint string was parsed as a URL but the scheme is missing (or not http/https). The exporter was built, but every export fails immediately because the HTTP client cannot dial a schemeless target. This is specific to the OTLP/HTTP (http/protobuf) exporter — the gRPC exporter uses host:port and does not go through net/http.
Symptoms
- Every OTLP/HTTP export fails with
unsupported protocol scheme ""(or a non-http scheme in the quotes). - The endpoint in the message has no
http://orhttps://prefix, e.g. a barecollector:4318/.... - Errors are immediate and deterministic, not intermittent — no network round-trip is attempted.
- gRPC pipelines to the same Collector work; only the HTTP exporter fails.
- Appeared after setting
OTEL_EXPORTER_OTLP_ENDPOINTto a bare host:port or copying a gRPC-style value. - No connection ever reaches the Collector; its receiver logs show nothing for the failing signal.
Common Root Causes
- Endpoint missing the scheme —
OTEL_EXPORTER_OTLP_ENDPOINT=collector:4318has nohttp://, so the parsed scheme is empty. - gRPC-style value on the HTTP exporter — a
host:portstring that is valid for gRPC is schemeless for HTTP. - Wrong scheme entirely — someone set
grpc://collector:4318, which HTTP cannot use. - Protocol/port mismatch —
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufpointed at the gRPC port4317with no scheme. - Trailing value from a template — a config templating bug drops the scheme, leaving
//collector:4318orcollector:4318. - Env var precedence confusion — a per-signal
..._TRACES_ENDPOINToverrides the base with a schemeless value.
Diagnostic Workflow
Print the endpoint the SDK actually uses and confirm whether it has a scheme — a bare host:port is the giveaway:
echo "$OTEL_EXPORTER_OTLP_ENDPOINT" # must start with http:// or https://
echo "$OTEL_EXPORTER_OTLP_TRACES_ENDPOINT" # per-signal override, if set
echo "$OTEL_EXPORTER_OTLP_PROTOCOL" # http/protobuf for the HTTP exporter
Set a proper absolute URL with a scheme. For the HTTP/protobuf exporter the endpoint is the base URL; the SDK appends /v1/traces, /v1/metrics, and /v1/logs per signal, so do not include the path yourself:
# Correct: scheme + host + HTTP port (4318), no signal path
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://collector.example.com:4318"
# TLS off (plaintext) uses http://
export OTEL_EXPORTER_OTLP_ENDPOINT="http://collector.example.com:4318"
If the exporter lives in a Collector’s own pipeline that forwards over OTLP/HTTP, the exporter’s endpoint must likewise be a full URL:
exporters:
otlphttp:
endpoint: https://collector-gateway.example.com:4318 # scheme REQUIRED
tls:
insecure: false
headers:
authorization: "Bearer ${API_KEY}"
retry_on_failure:
enabled: true
max_elapsed_time: 300s
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
Validate the config and confirm the corrected endpoint reaches the HTTP receiver:
otelcol-contrib validate --config /etc/otelcol-contrib/config.yaml
# Reachability of the HTTP receiver (expects 200/415, not a scheme error)
curl -v -m 5 https://collector.example.com:4318/v1/traces
Example Root Cause Analysis
A team standardized on a single OTEL_EXPORTER_OTLP_ENDPOINT value across services and set it to collector:4318, which had worked in their heads because the gRPC exporter accepts a bare host:port. But these services used the default http/protobuf protocol, so the HTTP exporter parsed collector:4318 as a URL with an empty scheme and every export failed instantly with Post "collector:4318/v1/traces": unsupported protocol scheme "". No spans arrived and the Collector’s receiver logged nothing, because no request ever left the app.
The fix had two parts. First, the endpoint gained a scheme and used the HTTP port: https://collector.example.com:4318. Second, the deployment made OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf explicit so the port (4318) and scheme (https://) were unmistakably HTTP. After redeploy the SDK appended /v1/traces itself and posted successfully; a curl -v to the receiver confirmed a real HTTP response instead of a scheme error. They added a deploy-time check that the endpoint starts with http:// or https://.
Prevention Best Practices
- Always give OTLP/HTTP endpoints a scheme —
http://for plaintext,https://for TLS — never a barehost:port. - Set
OTEL_EXPORTER_OTLP_PROTOCOLexplicitly so the exporter type, port (4318 HTTP vs 4317 gRPC), and scheme all agree. - Do not include the
/v1/tracessignal path in the base endpoint; the SDK appends it per signal. - Keep separate, clearly labeled endpoint values for gRPC (
host:port) and HTTP (https://host:port) to avoid cross-pasting. - Add a deploy/CI assertion that
OTEL_EXPORTER_OTLP_ENDPOINTmatches^https?://before rollout. - Reference tokens as
${API_KEY}in headers and keep them in secrets, never inline.
Quick Command Reference
# Show the endpoint the SDK reads — must start with http:// or https://
env | grep OTEL_EXPORTER_OTLP_ENDPOINT
# Set a correct HTTP/protobuf endpoint (scheme + HTTP port, no path)
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://collector.example.com:4318"
# Assert the endpoint has a scheme before deploy
[[ "$OTEL_EXPORTER_OTLP_ENDPOINT" =~ ^https?:// ]] && echo OK || echo "MISSING SCHEME"
# Confirm the HTTP receiver responds (not a scheme error)
curl -v -m 5 https://collector.example.com:4318/v1/traces
Conclusion
unsupported protocol scheme "" is an OTLP/HTTP-only error: the exporter was handed an endpoint with no http:// or https://, so Go’s HTTP client refuses to dial it. The fix is simply to make the endpoint a full absolute URL with the right scheme and HTTP port (4318), set OTEL_EXPORTER_OTLP_PROTOCOL to http/protobuf so nothing is ambiguous, and let the SDK append the signal path. Add a one-line deploy check that the endpoint starts with http and this class of error never ships.
Related
- OpenTelemetry Error Guide: ‘connection refused’ to the Collector
- OpenTelemetry Error Guide: ‘no such host’ on OTLP DNS resolution
- OpenTelemetry Error Guide: ‘rpc error: code = Unimplemented’
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.