OpenTelemetry Go "traces export: connection refused" (otlptrace) in CI
The Go otlptrace exporter dials a collector at localhost:4317 (gRPC) or 4318 (HTTP). In CI nothing listens there, so exports fail with connection refused, and TracerProvider.Shutdown may return the same error.
What this error means
Test output logs "traces export: Post ... dial tcp 127.0.0.1:4318: connect: connection refused" or the gRPC equivalent, and tp.Shutdown(ctx) returns a non-nil error the test does not handle.
traces export: Post "http://localhost:4318/v1/traces": dial tcp
127.0.0.1:4318: connect: connection refusedCommon causes
No collector on the OTLP port in CI
The exporter targets the default local OTLP endpoint. With no collector service, every gRPC/HTTP dial is refused.
Shutdown surfaces the export error
TracerProvider.Shutdown flushes pending spans; when the endpoint is dead it returns the connection error, which can fail a test that asserts err == nil.
How to fix it
Use a no-op or in-memory exporter in tests
- For unit tests, use
tracetest.NewInMemoryExporter()and assert on its spans. - For code that only needs a provider, use a provider without a network exporter.
- Do not fail the test on Shutdown when no collector is expected.
import "go.opentelemetry.io/otel/sdk/trace/tracetest"
exp := tracetest.NewInMemoryExporter()
tp := trace.NewTracerProvider(trace.WithSyncer(exp))
// exp.GetSpans() for assertionsRun a collector service if export is under test
Start a collector and set the endpoint env var when the test genuinely needs a live export.
env:
OTEL_EXPORTER_OTLP_ENDPOINT: http://otelcol:4317How to prevent it
- Use tracetest.InMemoryExporter for span assertions.
- Do not point tests at a live collector unless one runs in the job.
- Handle Shutdown errors instead of asserting they are always nil.