pulumi/pulumi · error

failed to start OTLP receiver: %w

Error message

failed to start OTLP receiver: %w

What it means

After an OTLP exporter is created, cmdutil starts the OTLP receiver; failure is wrapped with this message. On failure it shuts down the already-created span exporter before returning, so the wrapped error is the receiver's own startup error.

Source

Thrown at sdk/go/common/util/cmdutil/trace.go:250

	if endpoint == "" && logExporter == nil {
		return nil
	}

	var spanExporter otelreceiver.SpanExporter
	if endpoint != "" {
		var err error
		spanExporter, err = otelreceiver.NewExporter(endpoint)
		if err != nil {
			return fmt.Errorf("failed to create OTLP exporter: %w", err)
		}
	}

	receiver, err := otelreceiver.Start(spanExporter, logExporter)
	if err != nil {
		if spanExporter != nil {
			_ = spanExporter.Shutdown(context.Background())
		}
		return fmt.Errorf("failed to start OTLP receiver: %w", err)
	}

	ep := receiver.Endpoint()

	otelMu.Lock()
	otelReceiver = receiver
	logReceiverEndpoint = ep
	if spanExporter != nil {
		otelEndpoint = ep
	}
	otelMu.Unlock()

	if spanExporter != nil {
		// Start the AppDash bridge so that legacy OpenTracing plugins can send
		// spans that get converted to OTLP and forwarded to the same exporter.
		bridge, err := otelreceiver.StartAppDashBridge(spanExporter)
		if err != nil {
			_ = receiver.Shutdown(context.Background())

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Check for another process holding the receiver port (lsof -i / netstat) and kill it
  2. Re-run after confirming no stale pulumi processes remain (profile/trace listeners leak if the process crashed)
  3. Run in an environment that permits local socket binding
  4. Inspect the wrapped %w error for the bind/pipeline failure detail

Example fix

// before
lsof -i :4317  # stale process holding port
// after
kill <stale-pid>
pulumi up --trace=http://localhost:4317
Defensive patterns

Strategy: try-catch

Validate before calling

// verify no listener already occupies the receiver port
if l, err := net.Listen("tcp", "127.0.0.1:4317"); err != nil {
	return fmt.Errorf("receiver port busy: %w", err)
} else { l.Close() }

Try / catch

if err := startTracing(ctx, endpoint); err != nil {
	if strings.Contains(err.Error(), "failed to start OTLP receiver") {
		// likely port in use; clean stale processes then retry once
	}
}

Prevention

When it happens

Trigger: Calling the tracing setup with a valid endpoint/deferred exporter but otelreceiver.Start fails — e.g. the receiver cannot bind its local span-receiving port or its internal OTLP pipeline cannot initialize.

Common situations: Port already in use by another process (including a previously leaked pulumi process); sandbox restricting local port binding; OTLP collector misconfiguration preventing pipeline startup.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/2435bfe90d7bfb7d. Report an issue: GitHub.