redis/go-redis · error

failed to create Pub/Sub messages metric: %w

Error message

failed to create Pub/Sub messages metric: %w

What it means

Instrumentation of the native redisotel module creates OpenTelemetry metric instruments at recorder-init time. When the OTel meter cannot instantiate the Int64Counter for pub/sub message counts (e.g. a broken or nil MeterProvider, invalid instrument name/unit, or a failing SDK), createRecorder wraps and returns the underlying error. This is a startup-time failure, not a Redis connection problem.

Source

Thrown at extra/redisotel-native/redisotel.go:314

			dbconv.ClientConnectionPendingRequests{}.Name(),
			metric.WithDescription(dbconv.ClientConnectionPendingRequests{}.Description()),
			metric.WithUnit(dbconv.ClientConnectionPendingRequests{}.Unit()),
		)
		if err != nil {
			return nil, fmt.Errorf("failed to create connection pending requests metric: %w", err)
		}
	}

	var pubsubMessages metric.Int64Counter

	if cfg.isMetricGroupEnabled(MetricGroupPubSub) {
		pubsubMessages, err = meter.Int64Counter(
			MetricPubSubMessages,
			metric.WithDescription("The number of Pub/Sub messages sent or received"),
			metric.WithUnit("{message}"),
		)
		if err != nil {
			return nil, fmt.Errorf("failed to create Pub/Sub messages metric: %w", err)
		}
	}

	var streamLag metric.Float64Histogram

	if cfg.isMetricGroupEnabled(MetricGroupStream) {
		var streamLagOpts []metric.Float64HistogramOption
		streamLagOpts = append(streamLagOpts,
			metric.WithDescription("The lag between message creation and consumption in a stream consumer group"),
			metric.WithUnit("s"),
		)
		if cfg.histAggregation == HistogramAggregationExplicitBucket {
			streamLagOpts = append(streamLagOpts,
				metric.WithExplicitBucketBoundaries(cfg.bucketsStreamProcessingDuration...),
			)
		}
		streamLag, err = meter.Float64Histogram(
			MetricStreamLag,

View on GitHub (pinned to c5cad058c7)

Solutions

  1. Check that a valid OTel MeterProvider is registered via otel.SetMeterProvider before calling redisotel.Init
  2. Print the wrapped error (%w) to see the root cause from the meter SDK
  3. Verify the meter implements go.opentelemetry.io/otel/metric.Meter correctly and is not shut down
  4. Disable the metrics group via config options if metrics are not needed

Example fix

// before
err := redisotel.Init(client) // uses broken/absent MeterProvider
// after
otel.SetMeterProvider(sdktrace.NewTracerProvider()) // plus metric provider
err := redisotel.Init(client)
Defensive patterns

Strategy: validation

Validate before calling

if otel.GetMeterProvider() == nil || isShutdown(otel.GetMeterProvider()) {
	otel.SetMeterProvider(sdkmetric.NewMeterProvider())
}
err := redisotel.Init(client)

Try / catch

if err := redisotel.Init(client); err != nil {
	if strings.Contains(err.Error(), "Pub/Sub messages metric") {
		log.Fatalf("otel meter misconfigured: %v", err)
	}
}

Prevention

When it happens

Trigger: redisotel.Init / InstrumentMetrics (native path) calls createRecorder with a metric group including Pub/Sub enabled and meter.Int64Counter returns an error — typically a misconfigured global MeterProvider, an SDK that rejects the instrument, or an invalid custom meter.

Common situations: OTel SDK not registered or shut down before Init; using a Noop/noop meter wrapper with strict validation; name/unit conflicts with instrumention-level limits; custom WithMeter option passing an incompatible meter implementation.

Related errors


AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01). Data as JSON: /api/errors/db6c6cb049ea46bb. Report an issue: GitHub.