microsoft/aspire · error

trace exporter

Error message

trace exporter: %w

What it means

setupOTel wraps the error from otlptracegrpc.New, which constructs the gRPC OTLP trace exporter. This exporter creation can fail when the configured OTLP endpoint URL is malformed or unsupported, or when a required dependency (e.g. TLS credentials) is invalid. The error is wrapped with "trace exporter: %w" so the underlying cause is preserved.

Solutions

  1. Verify the OTLP endpoint URL has a valid scheme (http:// or https://) and host:port.
  2. Print the underlying error (%v of the wrapped err) to see the exact gRPC/URL failure.
  3. Ensure the exporter/collector (e.g. Aspire dashboard OTLP endpoint) is reachable and the address is correct.
  4. Confirm the OTLP Go SDK versions match (go.opentelemetry.io/otel + otlp exporters).

Example fix

// before
traceExp, err := otlptracegrpc.New(ctx, traceOpts...)
// after
endpoint := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
u, err := url.Parse(endpoint)
if err != nil || u.Scheme == "" {
    log.Fatalf("invalid OTLP endpoint %q: %v", endpoint, err)
}
traceOpts = append(traceOpts, otlptracegrpc.WithEndpoint(u.Host))
traceExp, err := otlptracegrpc.New(ctx, traceOpts...)
Defensive patterns

Strategy: validation

Validate before calling

ep := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
if u, err := url.Parse(ep); err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid OTLP endpoint %q", ep)
}

Try / catch

if err != nil {
    return nil, fmt.Errorf("trace exporter: %w", err)
}
// caller:
if err := setupOTel(...); err != nil {
    log.Printf("otel setup failed, continuing without traces: %v", err)
}

Prevention

When it happens

Trigger: Calling setupOTel with an invalid otlpEndpoint (e.g. missing scheme, unsupported scheme such as http:// vs grpc target parsing) causes otlptracegrpc.New to return an error; also caused by invalid TLS/credentials options.

Common situations: Misconfigured OTEL_EXPORTER_OTLP_ENDPOINT / endpoint URL in the AppHost environment, wrong scheme format passed through headers/endpoint wiring, or switching exporter protocol (grpc vs http) without updating the endpoint.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/5dbc7c16175c7b0d. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Cli/Templating/Templates/go-starter/api/telemetry.go:56

		resource.Default(),
		resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceName(serviceName),
		),
	)
	if err != nil {
		return nil, fmt.Errorf("otel resource: %w", err)
	}

	headers := otlpHeaders()

	traceOpts := []otlptracegrpc.Option{}
	if len(headers) > 0 {
		traceOpts = append(traceOpts, otlptracegrpc.WithHeaders(headers))
	}
	traceExp, err := otlptracegrpc.New(ctx, traceOpts...)
	if err != nil {
		return nil, fmt.Errorf("trace exporter: %w", err)
	}
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(traceExp),
		sdktrace.WithResource(res),
	)
	otel.SetTracerProvider(tp)

	metricOpts := []otlpmetricgrpc.Option{}
	if len(headers) > 0 {
		metricOpts = append(metricOpts, otlpmetricgrpc.WithHeaders(headers))
	}
	metricExp, err := otlpmetricgrpc.New(ctx, metricOpts...)
	if err != nil {
		return nil, fmt.Errorf("metric exporter: %w", err)
	}
	mp := sdkmetric.NewMeterProvider(
		sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExp)),
		sdkmetric.WithResource(res),

View on GitHub (pinned to 25830f84bd)